2013-11-29 4 views
2

Приносим извинения, если об этом ответили раньше, но я сам сводил с ума поиски ответа. Я использую таНос для создания массива:переполнение буфера malloc (C)

char *message = (char*) malloc(31 *sizeof(char)); 

Чтобы заставить пользователя ввести сообщение из максимум 30 символов:

fgets(message, 30, stdin); 

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

int length_message = strlen(message) - 1; 

char *temp1 = (char*) malloc(length_message * sizeof(char)); 

for(int i=0; message[i] != '\0'; i++) 
{ 
     temp1[i] = tolower(message[i]);  
} 

Но когда я пришел, чтобы отобразить новую строку

puts(temp1); 

Это показывает мой вход сообщение с последующим целым грузом тарабарщину на новой линии. Я не могу понять, откуда это взялось.

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

printf("length of temp array: %d", strlen(temp1)); 
printf("length of message: %d\n", length_message); 

Который вернул нужный length_message (количество вводимых символов пользователя в сообщении), но неправильный номер для длины моего массива temp! Я неправильно присвоил память для моего временного массива или неправильно написал ли я этому массиву?

Из чего я прочитал другие темы, у меня, похоже, есть ошибка переполнения буфера? Как я могу держать это под контролем?

Заранее благодарен!

ответ

1

Есть пара проблем с вашим кодом.

Фактическая ошибка вызвана тем, что вы не копируете завершающий символ 0 из исходной строки в пункт назначения. Вам нужно написать temp[i] = 0; после цикла for.

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

Другие проблемы включают в себя ужасныеcasting of void *, избыточные (и, следовательно, небезопасные) sizeof(char) и жесткий кодировкой буфер размер.

Вместо

char *message = (char*) malloc(31 *sizeof(char)); 

попробовать

#define BUF_SIZE 31 

char *message = malloc(BUF_SIZE); 
fgets(message, BUF_SIZE, stdin); 

или если вы чувствуете педантичным, то

char *message = malloc(BUF_SIZE * sizeof message[0]); 

но никогда использование жестко закодированных типа в sizeof(), когда вы malloc() в памяти. Но в любом случае, я не думаю, что вам нужно malloc(). Почему бы вам не использовать автоматический массив («выделенный стек», хотя это неправильное имя)? Тогда вы можете воспользоваться оператором sizeof при вводе пользователя.

Кроме того, strlen() и несколько других функций stdlib возвращаются size_t. Вы должны использовать этот тип, а не int.

+0

Большое вам спасибо за быстрый и полезный ответ. Какое преимущество имеет использование #define BUF_SIZE? В противоположность словам: char * message = malloc (31); – rus64

+0

@ rus64 Преимущество состоит в том, что у вас нет двух независимых жестко закодированных размеров, таким образом, вы менее вероятно испортите размер буфера при передаче в 'malloc()' и 'fgets()'. Представьте, что вы изменяете размер в 'malloc()' до 16, но вы забудете сделать то же самое для 'fgets()' ... результат ужасен. –

+0

Благодарю вас. «Вам нужно написать temp [i] = 0; после цикла for. Не уверен, что именно это мне даст? – rus64

3

Это:

strlen(message) - 1 

, конечно, должен быть таким:

strlen(message) + 1 

Вы сделали опечатку.

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