char *数组中的元素在复制到新数组时被破坏

时间:2011-12-22 17:22:04

标签: c arrays char allocation

我之前遇到过这个问题,答案是要对字符串进行空终止,要么确保为字符串分配足够的内存。以下是相关的代码片段:

for (z; z<mountable_volumes; z++)
{
main_items[z] = malloc(strlen(volumes[z])+2);
main_items[z] = volumes[z];
printf("main_items[%i]: %s\n", z, volumes[z]);
}
main_items[z] = NULL;
return main_items;

Volumes []是正确的,但当其内容被创建到main_items []时,它会变坏。我试过玩malloc,甚至直接分配方式比必要的更多ram。我还尝试在每个main_items []元素的末尾加上'\ 0'。我尝试过使用strcpy,strncpy,sprintf,结果相同。

以下是我的程序中的日志:

volumes[0]: Unmount /sdcard
volumes[1]: Mount /system
volumes[2]: Unmount /cache
volumes[3]: Mount /data
volumes[0]: Unmount /sdc)☻
main_items[1]: Mount /syste)☻
main_items[2]: Unmount /cac‼
main_items[3]: Mount /data

我错过了什么?谢谢!如果需要,我可以粘贴更多的功能。

编辑:

这是整个函数:(我已经应用了strndup()和free()提示)

char** get_mount_menu_options()
{
  Volume * device_volumes = get_device_volumes();
  num_volumes = get_num_volumes();

  char** volumes = malloc (num_volumes * sizeof (char *));

  int mountable_volumes = 0;
  int usb_storage_enabled = is_usb_storage_enabled();

  int i;
  for (i=0; i<num_volumes; i++)
  {
    volumes[i] = "";
    Volume *v = &device_volumes[i];
    char* operation;
if (is_path_mountable(v->mount_point) != -1)
      {   
    if (is_path_mounted(v->mount_point)) operation = "Unmount";
    else operation = "Mount";
    volumes[mountable_volumes] = malloc(sizeof(char*));
    printf("volumes[%i]: %s %s\n", mountable_volumes, operation, v->mount_point);
    sprintf(volumes[mountable_volumes], "%s %s", operation, v->mount_point);
    mountable_volumes++;
  }
}

char **main_items = malloc (num_volumes * sizeof (char *));

int z;
for (z=0; z<mountable_volumes; z++)
{     
main_items[z] = strndup(volumes[z], strlen(volumes[z]));
free(volumes[z]);
printf("main_items[%i]: %s\n", z, volumes[z]);
}
main_items[z] = NULL;
return main_items;
}

CURRENT LOG:

volumes[0]: Unmount /sdcard
volumes[1]: Mount /system
volumes[2]: Unmount /cache
volumes[3]: Mount /data
main_items[0]: Unmount /sdc)☻
main_items[1]: Mount /syste)☻
main_items[2]: Unmount ¿♠
main_items[3]:

谢谢大家!

3 个答案:

答案 0 :(得分:2)

要复制字符串,您需要使用strcpy()。作业不起作用!

strcpy(main_items[z], volumes[z]);

而且,

main_items[z] = malloc(strlen(volumes[z])+2);

应该是

main_items[z] = (char *) malloc(strlen(volumes[z]) + 1);

我认为main_items[z]volumes[z]char *

答案 1 :(得分:2)

作为strcpy()每个人的示例的替代方案,您可以使用strdup(),并跳过malloc()

main_items[z] = strdup(volumes[z]);

显然你仍然需要free()你的记忆!这也依赖于volumes[z]以NULL结尾。

编辑:或者,正如Peter Downs在评论中指出的那样,如果您知道字符串的长度,则可以使用strndup()而不是依赖于NULL终止。

答案 2 :(得分:1)

main_items[z] = volumes[z];应为strcpy(main_items[z], volumes[z]);,否则您在上面一行上分配的内存会被泄露,指针main_items[z]会变为volumes[z]中指针的别名