2014-10-03 2 views
2

Я пытался быть более «запоминающим» в своем программировании на языке C, когда узнал о методе malloc и подобных методах управления памятью. Однако, когда я попытался использовать realloc, чтобы выделить как можно меньше памяти для экземпляра char* в моей программе, я обнаружил, что он не содержит столько данных, сколько я думал.malloc и бесплатно: указатель, освобождаемый не был назначен

Вот мой код:

int foo(char * arg){ 
    if(condition){ 
     //code here 
    }else if(other_condition){ 
     char * cmd = malloc(5); 
     fgets(cmd,sizeof(cmd),stdin); 
     //more code here 
     if(another_condition){ 
      //more code 
      cmd = realloc(cmd,new_size) //once in this if block, but also once in another block 
      fgets(cmd,sizeof(cmd),stdin); 
      //more code 
     } 
     //more else-if blocks here 
     free(cmd) 
    } 
    //more else-if blocks here 
} 

Конкретно, в приведенном выше фрагменте кода, new_size был 255, хотя это было установлено в других размерах и в других местах. Проблема в том, что когда я запускаю программу, я получаю только 7 букв моего ввода.

Пример вывода:

... 
Enter filename: document1 
Loading file "documen" 
Load failed 
... 
(here the next time fgets is called it fails because "t1" is not valid input for the program) 

Я понимаю, что это получение "t1", потому что я не очищая входной буфер, но то, что я хочу, чтобы решить это то, что я только получать первые 7 символов вход. Если я вызываю sizeof(cmd) в середине, он говорит мне, что память, занятая cmd, - 8. Я также попытался выделить память с помощью char * cmd = malloc(5 * sizeof(char)) и cmd = realloc(cmd,255 * sizeof(char)), но это не решило проблему. Я должен, вероятно, упомянуть, что если я объявлю переменную, используя синтаксис char cmd[255], и я не звоню malloc, realloc или free в любом случае, эта проблема больше не возникает.

+0

Если вы находитесь на платформе, поддерживающей [GNU 'getline()'] (https://www.gnu.org/software/libc/manual/html_node/Line-Input.html), вы можете рассмотреть используя его - он помогает управлять динамическим распределением буфера для строк ввода (хотя вам потребуется переменная для отслеживания размера). –

+1

http://stackoverflow.com/questions/2478240/how-i-return-the-size-of-the-pointer-that-i-have-allocate-with-malloc –

ответ

2
fgets(cmd,sizeof(cmd),stdin); 

cmd Вот это char* вместо char[]. Таким образом, его размер всегда равен размеру указателя, а не размеру массива.

Вы должны отслеживать размер куска, выделенный вами.

+0

Есть ли способ использовать 'malloc' с 'char []'? Если я объявляю переменную с помощью 'char cmd [] = malloc (255)', то она говорит, что инициализатор массива должен быть списком инициализатора или строковым литералом. Существуют ли другие решения? Единственный способ освободить память 'cmd', чтобы дождаться выхода из области видимости? – Arc676

+0

№. Общее правило заключается в том, что вы должны явно знать (и обычно содержать - в переменной или поле) размер данных «malloc»-ed. Вы можете использовать гибкие члены массива, как в [этом ответе] (http://stackoverflow.com/a/23433573/841108) –

+0

@ Arc676 'char cmd [255];' вместо 'char cmd [] = malloc (255); ' –

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