在阵列中向上移动所有字符串(realloc问题)

时间:2009-04-08 08:44:28

标签: c

我正在尝试编写一个函数,将一个字符串数组中的所有元素向上移动一次。

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参数是一个指针数组吗?

由于

3 个答案:

答案 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())更容易,更快,并且可以阻止你浪费内存。