C 函数第二次运行时抛出异常

标签 c

这是我当前正在编写的函数的核心。

#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <ctime>
#include <cstring>

const char *words[] = {
    "pigu",
    // "third",
    // "country",
    // "human",
    // "define",
};
#define word_count (sizeof(words) / sizeof(char *))
const char *allowed_chars = "abcdefghijklmnopqrstuvwxyz";

const char *get_random_word()
{
    return words[rand() % word_count];
}

char *copy(const char *origin)
{
    char *str = NULL;
    str = (char *)malloc(sizeof(origin));
    strcpy(str, origin);
    return str;
}

int run()
{
    const char *selected_word = get_random_word();
    char *active_word = copy(selected_word);
    char *placeholder_word = copy(selected_word);
    char *left_chars = copy(allowed_chars);

    free(active_word);
    free(placeholder_word);
    free(left_chars);
    return 1;
}

int main(int argc, char *argv[])
{
    srand(time(NULL));
    while (run())
    {
    }
    printf("\n");
    return 0;
}

我已经删除了其他代码并设法将问题定位到 run函数,在这种情况下将无限运行,但是在调试时我在 run 内设置了断点功能。事实证明,运行函数 run 后第二次,程序在尝试执行 free(placeholder_word); 时崩溃。为什么会发生这种情况以及如何防止它。

最佳答案

您的copy函数错误,sizeof(origin)返回所需的字节数 在内存中存储指针,而不是字符串的长度。所以你已经分配了 错误的字节数以及字符串的长度是否大于 sizeof(origin) - 1,那么你就会溢出缓冲区,这会导致 未定义的行为可以解释段错误。

应该是

char *copy(const char *origin)
{
    char *str = NULL;
    str = malloc(strlen(origin) + 1);
    if(str == NULL)
        return NULL;
    strcpy(str, origin);
    return str;
}

请注意,我已经删除了 malloc 的强制转换,这在 C 中是不需要的。如果您 需要它,因为这是一个 C++ 程序,使用 new 而不是 malloc

并且在访问之前,您应该始终检查 malloc 是否返回 NULL 内存。

关于C 函数第二次运行时抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48716319/

相关文章:

C realloc(动态数组) - 访问冲突

c++ - 否定 float 总是安全的吗

c - 如何在 Contiki OS 的运行时执行不同的二进制文件?

c 系统调用 connect() 在客户端挂起(网络编程)

c++ - 将 char 数组中的数值存储到 VC++ 中的 INTEGER 变量中。

c - 没有任何语句的for循环

c - 如何将原始套接字绑定(bind)到特定接口(interface)

c++ - 我可以使用 clang 生成与旧 llvm 版本兼容的 llvm IR 吗?

c - 运行时检查 LeakSanitizer (detect_leaks=1)

c - 重用 ANTLR3 词法分析器和解析器