使用灵活数组重新分配结构

时间:2014-02-16 01:41:49

标签: c

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

我有以下代码:

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。我究竟做错了什么? If i take off the malloc statement in the middle it runs.另外,如果我尝试strcpy到arr->数组[arr-> size-1] .a,它会发生段错误。

任何帮助将不胜感激。 谢谢。

1 个答案:

答案 0 :(得分:0)

此代码存在许多问题,足以表明无论您遇到什么都无法复制。尽管如此,仍有足够的问题导致不稳定(即分段违规)。我假设您打算在s中使用小写str而不是S中的大写Str;这样才有意义。类似地,s中的小写strArray(应该是)。

为了使arr->size有用,您为此指定了arr->size++;值?这本身就是一个错误,但这又是另一个错误:

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

当你继续在关键的逻辑片段中继续使用未初始化的变量时,这是一个主要的问题,但是,一旦这个问题得到解决,下一个错误就是:

任何类似于模式X = realloc(X, Y);的东西都是可疑的。它是X es。那些应该是不同的。您 我的意思是,它已经工作,有点......但是没有更多的努力来正确地做到这一点,除非做得好,否则这不会成为{ {1}} - 友好。这对你来说应该是个大问题,因为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
不应假设{p> 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 被重新分配为一个更大的时候,你是否必须为新元素的字符串分配内存?

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

我认为通过字符串表示固定宽度,空填充字段可能有意义。修复字段的宽度使得在一维空间中表达数组变得更加容易。

否则,您应该保持字符串单独从列表节点中分配<...以下游程序员完全控制的方式,如果我虽然你在使用arrrealloc等的那一刻失去了它,但是当你使用VLA时,你会失去它,嗯!)...

  

我做错了什么?

我想我已经把您的代码分开了,足以说:

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

另外,如果我尝试strcpy到arr-&gt;数组[arr-&gt; size-1] .a,它会发生段错误。

是的,那么...... 再次出现幻影free相关问题!