2016-02-11 2 views
0

Я довольно новичок в C. У меня есть функция kstrfrom, которая должна создать и вернуть новый объект kstring, который содержит копию содержимого строки C с нулевым завершением, включая нулевой ограничитель.Выделение памяти и утечки памяти: C

Элемент .length возвращаемого kstring должен быть длиной cstr, плюс один для нулевого терминатора. Член .data должен быть указателем на вновь выделенную память, в которую вы скопировали содержимое cstr, включая нулевой байт в конце.

Если есть ошибка выделения памяти, эта функция должна вызывать abort() или вызывать неперехваченное исключение.

kstring kstrfrom(const char *cstr) 
    { 
     int length=1;  
     while(*cstr!='\0') 
     { 
      cstr+=1; 
      length+=1; 
     } 
     int i = 0; 
     kstring cdest={NULL,0}; 
     cdest.data = malloc(length+1); 
     if(cdest.data == '\0') 
     { 
      abort(); 
     } 
     else{ 
      while(cstr[i] != '\0') 
      { 
       cdest.data[i] = cstr[i]; 
       i++; 
      } 
     } 
     cdest.data[i] = '\0'; 
     cdest.data[++i] = '\0'; 

     return cdest; 
    } 

Я провел несколько тестовых случаев:

Test 9/ 26: kstrfrom gives correct length      skipped (0) 
    Test 10/ 26: kstrfrom contains null byte      succeeded (1) 
    Test 11/ 26: kstrfrom contains correct data      skipped (0) 
    Test 12/ 26: kstrfrom copies, not shares, data     skipped (0) 

Как вы можете видеть, что я нужна помощь давая правильную ссылку, содержащую правильные данные и копирование данных.

+0

Почему вы хранением нулевого терминатора в строке, если вы уже сохранить длину в 'length' члена? – stackptr

+2

'cstr + = 1;' К тому времени, когда вы определили 'length' строки,' cstr' указывает на окончание '\ 0'. – dxiv

+0

@dxiv является правильным. Если вы хотите итерации по строке, используйте временный указатель, а не оригинальный указатель. btw/это довольно неэффективно. (упростить), если вы знаете, что строка завершена нулем, используйте 'strlen (cstr)', чтобы получить длину, а затем цикл 'for()' для копирования. – pedwards

ответ

0

В конце

while(*cstr!='\0') 
    { 
     cstr+=1; 
     length+=1; 
    } 

Вы потеряли первоначальное значение ПРМ

попробовать

int length=1;  
    char * tmp = cstr; 
    while(*tmp!='\0') 
    { 
     tmp+=1; 
     length+=1; 
    } 

Вы не назначили члена длины ...

cdest.length = length + 1; 

Возврат kstr проблематично.

kstring res; 
res = kstrfrom("My String"); /* works */ 
kstrfrom("Another string"); /* leaks memory */ 

Другие комментарии описывают, как вы игнорируете языковые функции. Вашего код может быть достигнут более легко с ...

kstring kstrfrom(const char *cstr) 
{ 
    kstring cdest={NULL,0}; 
    cdest.data = strdup(cstr); 
    if(cdest.data == NULL){ 
     abort(); 
    } 
    cdest.length = strlen(cstr) + 1; /* not done in original example */ 
    return cdest; 
} 
Смежные вопросы