Рассмотрим char *a[] = {"abc", "xyz", "def"};
Как скопировать char * a [] на char ** b?
Deep копияchar *a[]
к char **b
.
Может кто-нибудь сказать, что такое глубокая копия? И сколько памяти нам нужно назначить b
?
Рассмотрим char *a[] = {"abc", "xyz", "def"};
Как скопировать char * a [] на char ** b?
Deep копияchar *a[]
к char **b
.
Может кто-нибудь сказать, что такое глубокая копия? И сколько памяти нам нужно назначить b
?
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?
Вы можете просто
Ь = а
Это назначит базовый адрес массива указателей * а [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.
Это не будет [глубокая копия] (http://en.wikipedia.org/wiki/Object_copy#Deep_copy). – interjay
Прогулка по 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
в конце массива.
На ваш первый вопрос будет дан ответ [здесь] (http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy) – Krishnabhadra
это это ваша домашняя работа? глубокая копия означает, что вы должны скопировать значения, а не только указатели, b требует 12 байтов – x4rf41
@ x4rf41, на платформах, где 'char' - один байт :) И это не касается указателей :) – StoryTeller