2017-01-15 8 views
0

Я хочу добавить нули в начале строки с этим методом:Добавить нули в строку в C

void addFrontzeros(char *str,int zeros) 
{ 
    if(zeros==0) 
    { 
     return; 
    } 

    char *temp=malloc((strlen(str)+1+zeros)*sizeof(char)); 

    int i=0; 
    for(;i<zeros;i++) 
    { 
     temp[i]='0'; 
    } 

    int j=0; 
    for(;j<strlen(str);j++) 
    { 
     temp[j+zeros]=str[j]; 
    } 
    temp[strlen(str)+zeros]=0; 
    str=realloc(str,(strlen(temp)+1)*sizeof(char)); 
    strcpy(str,temp); 
    free(temp); 
} 

Но когда я называю это из другого метода строка пуста после вызова. Строка Вызывающий выделяется, как это в другом методе:

char *mul = malloc(sizeof(char)*2); 
    mul[0]='0'; 
    mul[1]=0; 

С Valgrind я получил эту ошибку: Адрес 0x5201b00 составляет 0 байт внутри блока размером 2 free'd

Я думаю, что проблема с перераспределить, но я не имеют понятия, почему она не будет работать здесь

+2

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

ответ

5

позвонив realloc вы (возможно), изменяющее str внутри функции, но вызывающий addFrontzeros не видит новое значение str. Он по-прежнему имеет старую версию str, которая больше не указывает на действительные данные после realloc.

Ваша функция должна либо return str (чтобы ее можно было назвать x = addFrontzeros(x, n)), либо принять char **, чтобы он мог изменить указатель на месте.

Как указано StoryTeller, str = realloc(str, ...) небезопасен в случае, если realloc не работает. Во-первых, потому что вы не проверяете, вернул ли reallocNULL, а во-вторых, потому что если он делает , то возвращает NULL, у вас есть утечка памяти, потому что старый str по-прежнему выделен, но вы потеряли указатель на него. Минимальный способ справиться было бы

char *new_str = realloc(str, strlen(temp)+1); 
if (!new_str) { 
    perror("addFrontzeros: realloc"); 
} else { 
    str = new_str; 
} 

хотя, если вы хотите обрабатывать отказ каким-либо другим способом, вы можете, и оригинальный str будет оставаться действительным и неизменным.

Другая проблема заключается в том, что вы копируете только strlen(str) байт, который не включает завершающий нулевой байт, поэтому ваша строка некорректно завершена. Либо добавьте оканчивающийся нуль самостоятельно, либо просто скопируйте еще один байт (поскольку вы можете предположить, что str-, правильно законченный для начала).

Наконец, в качестве примечания стороны, sizeof(char) является 1 по определению, поэтому его умножение не нужно.

+1

Присвоение результата« realloc »слепому к существующему Указатель также небезопасен. – StoryTeller

+0

@StoryTeller, потому что при сбое он вернет 'NULL', но не изменит существующую память, поэтому слепое переназначение вызывает утечку, правильно? – hobbs

+0

Да, это то, что я имел в виду. Увидеть как отказ перераспределения не обязательно означает, что ваша программа является тостом (скажем, если «нули» огромны). Сбой в функции не должен изменять 'str'. – StoryTeller