gpt4 book ai didi

c - 重新分配具有灵活数组的结构

转载 作者:太空宇宙 更新时间:2023-11-04 04:45:14 25 4
gpt4 key购买 nike

我遇到了一个很奇怪的问题,

我有以下代码:

typedef struct{
char *a;
char *b;
char *c;
}Str;

typedef struct{
int size;
str array[]; //flexible array.
}strArr;

此处的目的是从realloc 中为新元素分配a、b 和c。

StrArr *arr;
int arrSize;
arrSize = 1;

arr = malloc(sizeof(strArr)+sizeof(int)*arrSize);
arr->size++;
arr = realloc(arr, sizeof(strArr)+sizeof(int)*arr->size);
arr->array[arr->size-1].a = malloc(sizeof(char)*75);
arr->size++;
card = realloc(arr, sizeof(strArr)+sizeof(int)*arr->size);

问题是:每当 arr 被重新分配为更大的一个时,您是否必须为新元素的字符串分配内存?如果运行此代码,它将失败,因为它给我 glibc detected at the second realloc。我究竟做错了什么? 如果我去掉中间的 malloc 语句,它就会运行。另外,如果我尝试将 strcpy 放入 arr->array[arr->size-1].a,它会出现段错误。

如有任何帮助,我们将不胜感激。谢谢。

最佳答案

这段代码有很多问题,足以表明您遇到的任何问题都无法重现。尽管如此,仍有足够的问题导致不稳定(即分段违规)。我假设您打算在 str 中使用小写的 s 而不是在 Str 中使用大写的 S ;只有这样才有意义。对于 strArray 中的小写 s(应该是)也是如此。

为了使 arr->size++; 有用,您在什么时候为 arr->size 分配了一个值?这本身就是一个错误,但与另一个错误交织在一起:

arr = realloc(arr, sizeof(strArr)+sizeof(int)*arr->size);

事实证明这是一个主要问题,因为您继续在关键逻辑部分中使用未初始化的变量,一次又一次,然而,一旦该问题得到解决,这里的下一个错误是:

任何类似于 X = realloc(X, Y); 模式的东西都是可疑的。它是 Xes。那些应该是不同的。您不应该像那样替换值。我的意思是,它会工作,有点......但正确地完成它并不需要更多的努力,除非正确地完成,否则这不会是 valgrind-友好的。这对您来说应该很重要,因为 valgrind 是帮助我们识别内存泄漏的工具!

您应该将其存储到一个临时变量中:

void *temp = realloc(X, Y);

... 然后您可以处理错误,可能是通过清理并正确退出:

if (temp == NULL) {
perror("realloc");
/* free(X); // what would valgrind cease complaining about? */
exit(EXIT_FAILURE);
}

... 并将 X 替换为 temp:

X = temp;

sizeof(int) 不应假设为与 sizeof str 相同的大小(无论 str 是什么)。鉴于 arr->array 的类型,我希望 sizeof str 或者,更好的是,这里有一个很好的模式要记住:

// X = realloc(Y, Z); or ...
void *temp = realloc(arr, sizeof *arr + arr->size * sizeof arr->array[0]);
// XXX: handle errors

The question is: whenever arr is realloc'd to be one bigger, do you have to allocate memory for the strings of the new element?

字符串本身应该位于列表节点的单独存储位置。这是什么?字符串和列表节点,在同一个数组中?!

我想如果您所说的字符串是指固定宽度、空填充字段,这可能是有道理的。固定字段的宽度使得在一维空间中表达数组变得更加容易。

否则,您应该让您的字符串与您的列表节点分开分配...以下游程序员完全控制的方式,如果我可以添加,有点不错,虽然你在使用 reallocmalloc 等的那一刻失去了它(因此在你使用 VLA 的那一刻,嗯!)...


What am I doing wrong?

我想我已经拆开你的代码足以说明:

  • 在使用变量之前初始化所有变量。在这种情况下,arr 指向一些变量,这些变量在没有首先被初始化的情况下使用。
  • 不要假设 sizeof(int)sizeof (/*any pointer type*/) 具有相同的宽度。在非常真实的系统中,这不会是真的。
  • 请记住使用 X = realloc(Y, Z); 模式,然后是错误处理,然后是 Y = X;
  • 我仍然不确定是否有必要强制下游程序员依赖malloc/realloc/etc 和free,或者在这里甚至有益。

Also, if i try a strcpy into arr->array[arr->size-1].a, it would segfault.

是的,好吧...又出现了与 arr->size 相关的问题!

关于c - 重新分配具有灵活数组的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21806173/

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