2013-06-05 4 views
-2

это то, что я до сих пор, но я не могу понять, что случилось с нимНаписать функцию, чтобы динамически создать новую копию строки и возвращает указатель на новую копию (C)

void newCopy(char *s) 
{ 
    char newString = malloc(sizeof(int * strlen(s))); 
    newString = s; 
    return &newString; 
} 
+0

Существует много плохого с вышеизложенным, не считая того, что выше фрагмент кода не будет даже компилировать (Пустота не является типом). Вы должны взглянуть на то, как вернуть выделенную память из функции в 'C'. –

+0

Ну, арендатор: 1) Должен возвращать символ 'char *'. 2) 'sizeof (int * strlen (s))' ерунда. 3) Вы не можете назначить 'char *' (from malloc) на 'char'. 4) Присвоение '' '' NewString'' (при условии, что 'newString' были правильно объявлены) просто скроет указатель на пространство, которое вы malloced. 5) Возврат '&' локальной переменной - это большой нет-нет - он возвращает адрес мусора. (Но не чувствую себя плохо - однажды в операционной системе IBM было однострочное подпрограммирование, в котором было что-то вроде 12 APAR (отчетов об ошибках), поданных против него.) –

+2

Вы также можете просто использовать strdup() – Max

ответ

4
void newCopy(char *s) 
{ 
    char newString = malloc(sizeof(int * strlen(s))); 

Первая и вторая проблемы здесь.

Во-первых, вы назначаете возврат malloc, который является указателем, переменной, объявленной как char. Переменная должна быть объявлена ​​как char*.

Во-вторых, ваш ввод sizeof неверен.

  • int * strlen(s) это вздор и не скомпилируется, потому что вы пытаетесь умножить тип и целое число. Вы имели в виду sizeof(int) (который является целым числом) * strlen(s) (также целое число), которое будет скомпилировано.
  • Вы должны использовать sizeof (char) вместо sizeof (int), так как это строка.
  • Вы должны добавить 1 к размеру, так как строки в C должны быть завершены нулем дополнительным \0, чтобы strlen не сообщал о том, что он является частью длины строки.

Собираем все вместе, sizeof(char)*(strlen(s)+1)

newString = s; 

Третья проблема здесь. = не является магическим оператором - он присваивает значение в переменной s (которое является указателем) к значению в переменной newString (которая после исправления вышеуказанной ошибки также будет указателем). Он ничего не делает.

Вместо этого вы должны использовать функцию strcpy, которая представляет собой функцию, которая копирует содержимое одной строки (путем указания ее указателя) на содержимое другой строки (следуя указателю). http://www.cplusplus.com/reference/cstring/strcpy/

return &newString; 

Четвертые и пятые проблемы находятся здесь.

В-четвертых, вы объявили функцию void, и здесь вы пытаетесь вернуть char *.

В-пятых, вы пытаетесь вернуть указатель на то, что было объявлено в стеке (локальная переменная). Как только функция вернется, что-либо в стеке для этой функции является мусором и больше не может быть указана.

Однако, если вы правильно сделать newString типа char*, все, что вам нужно сделать, это return newString; И вы правильно возвращает указатель на значение, которое указывает в кучу (благодаря ранее таНос).

} 

Наконец, судя по этому коду, я должен сообщить вам, что C не новичок дружественный язык, где вы можете просто ввести вещи, которые выглядят как «», что вы хотите, чтобы это произошло, и молюсь, чтобы это работает. Если вы даже слегка ошибаетесь, ваш код будет разбит, и у вас будет нулевая идея, потому что вы не знаете, как правильно это сделать. Либо прочитайте действительно хорошую книгу на C и научите себя всем от базового до продвижения шаг за шагом, чтобы вы знали, как все это работает, или заберите более удобный язык.

1

Начну с того, что, на мой взгляд, учитывая количество и (особенно) характер ошибок в этом коде, вам, вероятно, понадобится get a good book on C.

Ваш newString = s; перезаписывает указатель вместо копирования строки в пространство, которое вы только что выделили. Таким образом, вы теряете указатель на то, что вы просто выделяете (утечка памяти), не делая копию. Вероятно, вы захотите использовать strcpy вместо прямого назначения.

Ваши вычисления по размеру, который вы выделяете, не то, что вы действительно хотите. Как правило, для строки длины N вы хотите выделить N + 1 байт. Вы в настоящее время пытаетесь выделить sizeof(int * strlen(s)) байтов, которые даже не должны компилироваться.

0

Исправленная версия должна быть, как:

char *newCopy(char *s) 
{ 
    if (s == NULL) 
    return NULL; 
    char *newString = malloc(strlen(s) + 1); 
    if (newString == NULL) 
    return NULL; 
    strcpy(newString, s); 
    return newString; 
} 
+0

Возможно, вы захотите добавить : 'if (newString! = NULL)' перед 'strcpy (newString, s);' –

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