这是我的代码
#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)
当您malloc
为 最初指向的一个元素留出空间时a
,您实际上从未初始化该内存。因此,**a
未初始化,因此读取它被认为是未定义的行为。在实践中,我怀疑有时分配给您的内存在某些情况下是空指针,而在其他情况下则不是,这是造成片状的原因。
我实际上认为您甚至不需要检查*a
和**a
。只要指针a
本身不是空指针,您就可以修改它指向的指针 ( *a
)。此外,这里实际上并不需要知道所指向的数组的第一个元素是否*a
为 null( **a
)。所以你可以用
if (a)
我会更进一步,甚至不会为 分配初始数组a
,因为您实际上永远不会读取存储在那里的值。
其他要做的事情:该函数append
返回一个状态代码,通知操作是成功还是失败。每次调用时检查该值是一个好主意append
,以防万一失败。您可能还想将外部if
语句更改为 an,assert
以便如果有人使用错误参数调用它,它会停止并报告违反前提条件的情况,而不是失败并返回错误代码。毕竟,如果问题是“你给了我不可能正确的论点”,那就意味着代码中的某处存在逻辑错误。
希望这可以帮助!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句