我正在尝试编写一个函数,将一个字符串数组中的所有元素向上移动一次。
void shift_frags(char **frags, int frag_len, int cur)
{
int i;
for(i = cur; i < frag_len-1; i++)
{
if(strlen(frags[i+1]) > strlen(frags[i]))
frags[i] = realloc(frags[i], strlen(frags[i+1])*sizeof(char));
strcpy(frags[i], frags[i+1]);
}
free(frags[frag_len-1]);
}
这给了我错误:“realloc():下一个大小无效:...”每个数组被动态分配为从文件读取的字符串的大小。我不应该能够动态分配新的数组大小,因为我的frags参数是一个指针数组吗?
由于
答案 0 :(得分:3)
因为你说数组只是一个指针数组,所以你不需要执行任何重新分配。你只需要自己复制指针。只需要对数组部分中的memmove或类似内容进行简单调用即可。
近似于此的东西。
void shift_frags(char **frags, int frag_len, int cur)
{
free(frags[frag_len]);
memmove(frags+cur+1, frags+cur, (frag_len-cur) * sizeof(char*));
}
答案 1 :(得分:2)
根本不需要free()
/ realloc()
。
你的char **frags
是一个指向指针列表的指针,所以你可以在不创建新字符串的情况下随机调整指针值。
请确保从列表的最远端开始,向后计数,或使用memmove()
:
void shift_frags(char **frags, int frag_len, int cur)
{
int i;
free(frags[frag_len]); /* because otherwise this is left dangling */
for(i = frag_len; i > cur; i--)
{
frags[i] = frags[i - 1];
}
}
或:
void shift_frags(char **frags, int frag_len, int cur)
{
int n = frag_len - cur;
frags += cur;
free(frags[n]);
memmove(frags + 1, frags, n * sizeof(*frags)); /* nb: memmove(dst, src, n) */
}
注意:这里有一个可能的off-by-one错误,它取决于你的frag_len值的语义,以及你是否知道frag
内存块已经足够大以容纳另一个指针。< / p>
答案 2 :(得分:1)
您的realloc可能会失败,因为您没有为字符串中的尾随NUL('\ 0')字符保留一个字节 - 为您的realloc大小添加+1:
if(strlen(frags[i+1]) > strlen(frags[i]))
frags[i] = realloc(frags[i], (strlen(frags[i+1]) + 1)*sizeof(char));
strcpy(frags[i], frags[i+1]);
将修复该错误。您获得的具体错误可能是因为您的一个字符串长度为0,而realloc(foo,0)只是在您的系统上给出了该错误,或者因为您在未分配的内存中编写了尾随'\ 0'而覆盖其他重要的东西,造成腐败。
简单地重新排列指针(frags [i] = frags [i + 1],或使用memmove())更容易,更快,并且可以阻止你浪费内存。