2013-04-24 4 views
1

Рассмотрим char *a[] = {"abc", "xyz", "def"};Как скопировать char * a [] на char ** b?

Deep копияchar *a[] к char **b.

Может кто-нибудь сказать, что такое глубокая копия? И сколько памяти нам нужно назначить b?

+0

На ваш первый вопрос будет дан ответ [здесь] (http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy) – Krishnabhadra

+5

это это ваша домашняя работа? глубокая копия означает, что вы должны скопировать значения, а не только указатели, b требует 12 байтов – x4rf41

+0

@ x4rf41, на платформах, где 'char' - один байт :) И это не касается указателей :) – StoryTeller

ответ

1
char *a[n]; 

Является массивом из n указателей на символ. Каждый элемент массива смещен в памяти. Размер в памяти, необходимой является

sizeof(char *) * n 

Я использовал оператор SizeOf() здесь ... можно предположить, 4 байта для указателя, но это может быть не безопасно ... это зависит от вашего оборудования.

char **b 

Немного отличается. Это указатель на точку-символ. ** b не выделил массив указателей. Во-первых выделить массив ...

char **b = malloc(sizeof(char *) * n); 

EDIT: Спасибо interjay за указание свою ошибку ... ниже пример теперь использует strdup(), чтобы выделить память для каждого б [я]

** b указывает на начало массива из n указателей. Для каждого указателя в этом массиве вы могли бы сделать так: b [0] = a [0] для мелкие копии

Это мелкая копия, так как b [0] укажет на ту же память, что [0] указывает к. Таким образом, изменение содержимого b [0] изменит содержимое файла [0].

Глубокая копия подразумевает, что у вас есть два полностью независимых объекта ... поэтому изменение содержимого b [0] не приведет к изменению содержимого [0]. Это означает, что для каждого b [i] вам нужно выделить новую память и скопировать строку из [i] в ​​этот новый блок.

Для глубокой копии:

char *a[n]; 
// ...intialise array a.... 
char **b = malloc(sizeof(char *) * n); // allocate array of pointers 
if(b) 
{ 
    int i = 0; 
    for(; i < n; ++i) 
     b[i] = (char *)strdup(a[i]); // allocate memory for new string and copy string 
} 
else 
    printf("You ran out of memory!\n"); 

Как asside ... вы использовали постоянные строки, так что вы не должны технически изменить их ...

char *xxx = "String"; 
char yyy[] = "String"; 

Вы можете безопасно изменить содержимое yyy. Обычно вы можете изменять содержимое xxx без каких-либо проблем, но обратите внимание: поскольку в момент компиляции выделена строка, вы можете обнаружить, что компилятор, например, поместил ее в постоянное запоминающее устройство.

EDIT: Там, кажется, были дебаты о том, чтобы бросить возвращения из таНоса (!, Который я был в привычке делать, но мне кажется, что это плохая привычка) ... см Why do we need to cast what malloc returns?

+0

Вам нужно выделить память для каждого 'b [i]'. – interjay

+0

@interjay: Да, ваше право, спасибо, что заметили это! – Jimbo

+0

malloc() возвращает void *, вам нужно наложить его –

-1

Вы можете просто

Ь = а

Это назначит базовый адрес массива указателей * а [3] б.

Теперь вы можете получить доступ с помощью строки б

for example string 1 can be accessed by *(b+0) gives address of string 1 
      string 2 "    " *(b+1) "    " string 2 
      string 3 "    " *(b+2) "    " string 3 

Поскольку вы назначаете массив указателей на указатель на указатель вы уже присваивающую память б Следовательно, вам не нужно использовать таНос.

Только когда вы указываете некоторые данные указателю во время выполнения, и вы не указали память на указатель в своей программе, тогда используйте malloc.

+1

Это не будет [глубокая копия] (http://en.wikipedia.org/wiki/Object_copy#Deep_copy). – interjay

1

Прогулка по a массива, для ЭАГ a[i] запроса пространства Alloc его с помощью одного из *alloc() семейных функций и поместить результат в соответствующем b[i]. Указатели b сами должны быть указателем с достаточным пространством для удержания числа строк в a в качестве указателей. Рассчитайте с чем-то вроде этого:

int bsize = (sizeof(a)/sizeof(a[0])) * sizeof(char*); 
    char **b = malloc(bsize); 
    int i,len; 
    /* if(b == NULL) /* error: no memory */ 
    for(i = 0,len = sizeof(a)/sizeof(a[0]); i < len; i++) { 
     char *tmp = malloc(strlen(a[i])+1); 
     if(tmp == NULL) /* error: no memory */ 
     strcpy(tmp, a[i]); 
     b[i] = tmp; 
    } 

Обратите внимание, что вам нужно или держать размер b массива в памяти либо положить NULL в конце массива.

+0

dowvotes? Комментарии? – Jack

+0

Нижняя сторона может быть вызвана использованием 'sizeof (int)' вместо 'sizeof (char *)' для вычисления 'bsize' или неопределенной переменной' tmp'. – Armali

+0

@Armali Fixed .. – Jack

Смежные вопросы