2013-10-04 3 views
0

Я пытаюсь выделить память, сохранить строку и распечатать ее, но я думаю, что она не сработала.Выделение памяти для строки

#include<stdio.h> 
#include<windows.h> 
int main() 
{ 
    char* allochere; 
    allochere = malloc(sizeof(char)); 
    *allochere = "Hello"; 
    printf("%s",allochere); 


    return 0; 
} 
+0

1) «sizeof (char)» всегда 1. Это вам не нужно, вы не хотите этого. Вместо этого укажите длину * ACTUAL *. 2) Длина для «Hello» будет 6: H, e, l, l, o, \ 0: 'allochere = malloc (6);' 3) Используйте 'strcpy()' для копирования «Hello» в allochere. Простое присваивание просто устанавливает значение указателя, а не содержимое строки. – paulsm4

ответ

3

Присваивание *allochere только присваивает значение первого символа в строке неинициализированного. Назначенное значение бессмысленно для загрузки, поскольку правая часть задания является указателем. (. Если вы включите компиляции предупреждений, компилятор будет предупреждать вас о проблемах с таким заданием)

Чтобы правильно инициализировать строку, вам нужно вызвать strcpy скопировать строку:

strcpy(allochere, "Hello"); 

Кроме того, вам нужно выделить allochere с правильным размером, чтобы держать строку, которую вы намерены поставить там:

allochere = malloc(strlen("Hello") + 1); 
+0

Исправьте меня, пожалуйста, если я ошибаюсь: * allochere является разыменованным указателем на char ... allochere является указателем на выделенную память ... & allochere является адресом allochere! – user2836131

+0

@ user2836131 Эти утверждения верны. – user4815162342

1

вы не выделять достаточно памяти для хранения слово «Hello» - вам нужно выделить место для 5 символов плюс завершающий байт, поэтому y НУ следует заменить таНос вызов:

allochere = malloc(6); 

Вы не можете присвоить строковый литерал allochere, потому что вы пропустите указатель на выделенную память. Вместо этого, выделив достаточно места, используйте команду strcpy:

strcpy(allochere, "Hello"); 
+0

Сторона примечания: sizeof (char) всегда 1; malloc (sizeof (char)) совпадает с malloc (1). –

+1

Почему вы рекомендуете отличать возвращаемое значение 'malloc()'? Это здравый смысл, что это плохо. – glglgl

+0

Хорошая точка. Я не рекомендую это, это просто привычка. Я просто удалю его из своего кода, так как это явно не хороший совет. Спасибо за головы;) –

1

Вам нужно что-то вроде этого.

#include<stdio.h> 
#include<windows.h> 

int main() 
{ 
    char* allochere; 

    allochere = malloc(strlen("Hello") + 1); 

    strcpy(allochere, "Hello"); 
    printf("%s\n", allochere); 

    return 0; 
} 
+2

why' #include '? – user4815162342

+0

В системах unix/linux/bsd мы обычно включаем для получения декларации для malloc. С окнами все ставки отключены. Он делает вещи «по-другому». Я просто предположил, возможно, неправильно, что - это объявление malloc. –

+0

ОП не упоминал Windows в вопросе. Но даже если бы он это сделал, я не буду следовать вашим рассуждениям. Windows делает многое по-другому, чем Unix, но поддерживает компиляторы, которые поддерживают стандартные функции C 'malloc',' strcpy' и 'printf', не прибегая к заголовкам, специфичным для платформы. Вы пробовали просто включить ''? – user4815162342

2

Здесь несколько ошибок.

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

Во-вторых, вы неправильно назовете malloc(). Если вы хотите выделить память для N-буквенной строки, вы должны написать malloc(N + 1); (+1, потому что нулевой байт также должен иметь свою ячейку).

И, наконец, вы должны использовать функцию типа strcpy, чтобы скопировать строку в пункт назначения. В этом случае вы должны позвонить strcpy(allochere, "Hello").

Ваш код должен выглядеть следующим образом:

char* allochere; 
allochere = malloc(6*sizeof(char)); 
strcpy(allochere, "Hello"); 
printf("%s", allochere); 

... 

// don't forget to deallocate the memory 
free(allochere); 
+0

«вы должны написать' (char *) malloc (N + 1); '' Нет. Вы должны написать 'malloc (N + 1);' "без скрытия ошибок' (char *) '. – glglgl

+0

+ 1: Отличный ответ, PiotrK – paulsm4

+0

Существует еще одна потенциальная ошибка. Выделенная память не является явно свободной() d после использования, поэтому существует вероятность утечки памяти, особенно если этот код скопирован где-то еще. в этом примере - это неявно free() d, когда main() возвращает - это плохая практика вообще, и любой статический анализатор, заслуживающий ее соли, должен ее отмечать. –

2

Этот код не имеет никакого смысла.

char *allochere; 

'allochere' - указатель на символ, другими словами, строку.

allochere = malloc(sizeof(char)); 

Теперь вы выделяете один символ и указываете на него «allochere». Кстати, sizeof(char) всегда 1.

*allochere = "Hello"; 

Теперь вы установили первый символ «allochere» к «сопзЬ символ *», компилятор будет блевать здесь. Теперь укажите точки на случайные данные, а не на строку.

Посмотрим на некоторые альтернативы, которые работают.

char *allochere; 
allochere = "Hello"; 
printf("%s", allochere); 

char *allochere; 
allochere = strdup("Hello"); 
printf("%s", allochere); 

char *allochere; 
allochere = malloc(strlen("Hello") + 1); 
strcpy(allochere, "Hello"); 
printf("%s", allochere); 
+0

Обратите внимание, что strdup() содержит неявный malloc(). Возвращенный char * должен быть бесплатным() d, как и любая другая память, выделенная кучей. –

0

В этом случае вам нужно на самом деле копировать данные непосредственно из строки постоянной "Hello" в ваше выделенное пространство. Однако, прежде чем мы даже доберемся туда, есть пара вопросов.

  1. Убедитесь, что вы выделяете достаточно места.

    Вы назначаете sizeof один символ, недостаточно для того, чтобы удерживать всю строку (5 символов в «Привет» плюс еще один для нулевого терминатора). Вы можете сделать это с

    allochere = malloc(6); 
    

    или использовать общую конвенцию

    allochere = malloc(strlen("Hello") + 1); 
    

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

  2. Вам необходимо скопировать данные, потому что назначение строк не совсем точно определяет, что вы пытаетесь сделать. Делая

    *allochere = "Hello"; 
    

    Вы фактически присваивая значение в allochere быть адрес "Hello". Если вместо того, чтобы вы сделали это:

    allochere = "Hello"; 
    

    Это может реально работать (в некоторых системах - Я не уверен, и не проверял), но это потому, что вы назначаете и адрес на адрес.

    Однако, вы находитесь malloc данные, что означает, что вы хотите скопировать данные. Таким образом, вы захотите использовать что-то вроде strcpy для копирования из местоположения в выделенную строку. Следовательно:

    strcpy(allochere, "Hello"); 
    
  3. Последняя проблема заключается в том, чтобы фактически видеть выход. Поскольку вы используете printf, вам нужно будет очистить данные до экрана. printf автоматически очистит данные, если у вас есть символ новой строки ('\n'), но вы также можете использовать fflush().

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