gpt4 book ai didi

c - 为什么这段代码通常可以运行但有时会产生Segmentation Fault?

转载 作者:行者123 更新时间:2023-12-01 12:05:53 24 4
gpt4 key购买 nike

这是我的代码

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

/**************************************************
a is a pointer to an array of strings
b is a string
This function appends b to *a
n is the number of strings currently "held" by *a
**************************************************/
int append(char ***a, char *b, unsigned long n) {
if (a && *a && **a) {
char** tmp = realloc(*a, (n + 1) * sizeof(**a));
if (tmp) {
tmp[n] = b;
*a = tmp;
return 0;
}
}
return -1;
}

void test() {
char *words[7] = { "food", "is", "good", "to", "eat,", "like", "pizza" };
char** a = malloc(1 * sizeof(*a));

for (int i = 0; i < 7; i++) {
append(&a, words[i], i);
int j = 0;
while (j <= i)
printf("%s ", a[j++]);
printf("\n");
}
}

int main() {
test();
return 0;
}

代码总是可以正常编译并且没有警告。可执行文件在大约 95% 的时间内按预期运行。但是大约 5% 的时间,我会遇到段错误。我知道错误发生在 a[j++] 但我不明白为什么。

最佳答案

看看这一行:

if (a && *a && **a)

当您为 a 最初指向的一个元素malloc 空间时,您实际上从未初始化该内存。结果,**a 未初始化,因此读取它被认为是未定义的行为。在实践中,我怀疑有时分配给您的内存在某些情况下是空指针,而在其他情况下则不是,这就是易碎性的原因。

我实际上认为您甚至不需要检查 *a**a。只要指针 a 本身不是空指针,您就可以修改它指向的指针 (*a)。此外,这里实际上不需要知道 *a 指向的数组的第一个元素是否为 null (**a)。所以你可以把这张支票换成

if (a)

我会更进一步,甚至不为 a 分配初始数组,因为您实际上永远不会读取存储在那里的值。

其他要做的事情:append 函数返回一个状态码,通知操作是成功还是失败。最好在每次调用 append 时检查该值,以防它失败。您可能还想将外部 if 语句更改为 assert 以便如果有人使用错误参数调用它,它会停止并报告违反前提条件而不是失败一个错误代码。毕竟,如果问题是“你给我的论点不可能是正确的”,这意味着代码中某处存在逻辑错误。

希望这对您有所帮助!

关于c - 为什么这段代码通常可以运行但有时会产生Segmentation Fault?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57013686/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com