элементы в массиве char * повреждаются при копировании в новый массив - PullRequest
0 голосов
/ 22 декабря 2011

Я сталкивался с этим раньше, и ответом было либо завершить строку строкой с нулевым символом, либо убедиться, что выделено достаточно памяти для строки. Вот соответствующий фрагмент кода:

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;

Объемы [] верны, но когда их содержимое создается в main_items [], все идет плохо. Я пытался играть с malloc, даже напрямую выделяя больше оперативной памяти, чем необходимо. Я также попытался прикрепить '\ 0' к концу каждого элемента main_items []. Я попытался использовать 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

Чего мне не хватает? Спасибо! Я могу вставить больше функции, если это необходимо.

EDIT:

вот вся функция: (я применил подсказки 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;
}

ТЕКУЩИЙ ЖУРНАЛ:

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 ]

2 голосов
/ 22 декабря 2011

Для копирования строк необходимо использовать 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 *

2 голосов
/ 22 декабря 2011

В качестве альтернативы всем strcpy(), вы можете просто использовать strdup() и пропустить malloc():

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

Очевидно, вам все еще нужно free() вашей памяти!Это также зависит от того, что volumes[z] завершается по NULL.

Редактировать: Или, как отмечает Питер Даунс в комментариях, вы можете использовать strndup() вместо того, чтобы полагаться на NULL-завершение, если вы знаете длину ваших строк.

1 голос
/ 22 декабря 2011

main_items[z] = volumes[z]; должно быть strcpy(main_items[z], volumes[z]);, в противном случае память, выделенная в строке чуть выше, просачивается, и указатель main_items[z] становится псевдонимом указателя в volumes[z].

...