将字符串添加到数组,未分配指针realloc&d; d

时间:2016-08-27 19:17:44

标签: c

我正在尝试实现一个方法,将一个给定的字符串添加到以NULL指针结尾的数组中。这是我到目前为止所得到的,但我收到一个错误,指出指针是realloc&d; d未被分配。

int main(void)
{
    char **strings = init_array();

    strings = add_string(strings, "one");
    strings = add_string(strings, "two");

    return 1;
}


char **init_array(void)
{
    char **array = malloc(sizeof(char *));
    array[0] = NULL;
    return array; 
}


char **add_string(char **array, const char *string)
{
    unsigned int size = 0;
    while (*array) {
        size++;
        array++;
    }

    char **newarr = (char **)realloc(array, sizeof(char *) * (size + 2));

    newarr[size] = malloc(strlen(string)+1);
    strcpy(newarr[size], string);
    newarr[size+1] = NULL;

    return newarr;
}

5 个答案:

答案 0 :(得分:2)

问题是array++。你必须传递realloc返回的相同值malloc(你的array参数),但是你在循环中修改它,所以它只能在第一次工作(因为{{1}将立即错误)。你可以使用:

*array

其余部分保持不变。

答案 1 :(得分:1)

while (*array)循环中,您不仅会增加size,还会增加array指针本身。因此,在循环结束时size包含数组的长度,array指针指向最后一个(NULL)元素。此指针从未被分配(它指向一个已分配的块),因此它不是重新分配的有效指针。 (当然这不是你打算做的。)

所以,不要在那个循环中做array++

答案 2 :(得分:1)

计算数组中字符串数量的循环也会使变量本身前进。您可以使用临时变量:

char **temp = array;
while (*temp)
     ...

或将计数分成一个函数。

顺便说一句,在使用realloc时,您不需要投射,原因与您不使用malloc进行投射相同。这不是一个错误,但最好是一致的。

答案 3 :(得分:1)

总结到目前为止给出的所有其他答案,添加一些最佳实践调整,相关代码应如下所示:

char **add_string(char **array, const char *string)
{
  char ** newarr;
  size_t size = 0;

  assert (NULL != string); /* Need to include assert.h */

  if (NULL != array)
  {
    while (NULL != array[size]) 
    {
      ++size; /* Just count, do not touch the pointer value allocated. */
    }
  }

  newarr = realloc(array, (size + 2) * sizeof *newarr);
  if (NULL == newarr) /* Test the outcome of reallocation. */
  {
    perror("realloc() failed"); /* Need to include stdio.h */
    return NULL;
  }

  newarr[size] = malloc(strlen(string) + 1);
  if (NULL == newarr[size])
  {
    perror("malloc() failed"); /* Need to include stdio.h */
    /* Might want to clean up here and indicate the failure to the 
       caller by returning NULL. */
  }
  else
  { 
    strcpy(newarr[size], string);  
  }

  newarr[size+1] = NULL;

  return newarr;
}

甚至更严格:

char **add_string(char **array, const char *string)
{
  assert (NULL != string); /* Need to include assert.h */

  {
    size_t size = 0;

    if (NULL != array)
    {
      while (NULL != array[size]) 
      {
        ++size; /* Just count, do not touch the pointer value allocated. */
      }
    }

    {
      char ** newarr = realloc(array, (size + 2) * sizeof *newarr);
      if (NULL == newarr)
      {
        perror("realloc() failed"); /* Need to include stdio.h */
      }

      if (NULL != newarr)
      {  
        newarr[size] = malloc(strlen(string) + 1);
        if (NULL == newarr[size])
        {
          perror("malloc() failed"); /* Need to include stdio.h */
        }
        else
        { 
          strcpy(newarr[size], string);  
        }

        newarr[size+1] = NULL;
      }

      return newarr;
    }
  }
}

答案 4 :(得分:0)

最简单的方法是保留初始数组指针并使用它来重新分配内存。

int main(void)
{
    char **strings = init_array();

    strings = add_string(strings, "one");
    strings = add_string(strings, "two");

    return 1;
}


char **init_array(void)
{
    char **array = malloc(sizeof(char *));
    array[0] = NULL;
    return array; 
}


char **add_string(char **array, const char *string)
{
    char** cache = array;
    unsigned int size = 0;
    while (*array) {
        size++;
        array++;
    }

    char **newarr = (char **)realloc(cache, sizeof(char *) * (size + 2));

    newarr[size] = malloc(strlen(string)+1);
    strcpy(newarr[size], string);
    newarr[size+1] = NULL;

    return newarr;
}

另一个注意事项 - 主要功能应该在成功时返回0。