2016-04-28 3 views
0

в этом коде я хочу, чтобы получить количество друзей, а затем получить имена я хочу строки будут выделяться динамически с Lengh пользовательского ввода я использовал с 2-мя функциями:динамический символьные указатели массива в строки

void getNum(char** names, int* num) 
{ 
    //somecode 
    names = (char*)malloc(*num * sizeof(char)); 
    //check 
} 

void getNames(char** names, int* num) 
{ 
    int i = 0; 
    int len = 0; 
    char name[LEN] = { 0 }; 

    getchar(); //buffer cleaning 
    for (i = 0; i < *num; i++) 
    { 
     printf("enter #%d friend name: ", i+1); 
     myFgets(name, LEN); //getting name and cleaning "\n" at end 
     len = strlen(name)+1; // getting the size of string include "/0" 
     *(names + i) = (char*)malloc(len * sizeof(char)); 
     if (*(names[i]) == NULL) 
     { 
      printf("Error allocating memory!\n"); //print an error message 
      return 1; //return with failure 
     } 
     strncpy(*names, name, len); 
    } 
} 

Второе динамическое распределение doens't для меня работает, переполнение: «Доступ к месту записи нарушения прав доступа». Если первое распределение будет во второй функции, оно будет работать нормально. Можете ли вы объяснить это? и что мне нужно сделать для этого, будет работать таким образом? спасибо заранее ...

+0

Compile с все предупреждения включены. И, пожалуйста, покажите, как вы называете 'getnames' и' getNum'. –

+1

Я предполагаю: 'names = (char *) malloc (* num * sizeof (char));' должно быть 'names = (char *) malloc (* num * sizeof (char *));' – LPs

+1

Наверху неверно, 'getNum' кажется довольно бессмысленным, поскольку он вызывается * nothing * в опубликованном коде. – WhozCraig

ответ

1

Предполагая, что первая функция должна выделить массив указателей, и что второй должен выделить отдельные массивы символов для хранения отдельных имен, вам не хватает уровня разыменования в первой функции:

  • вы передаете его в копия char** (параметры прохода C по копиям)
  • Вы используете только локальную копию для хранения результата malloc (что неверно BTW) и по-прежнему сохраняете исходное значение в вызывающем абоненте и в конечном итоге получаете утечку памяти при выходе из функции поскольку ничего больше не указывает на выделенный блок

Оно должно быть:

char** getNum(int num) /* no need to pass num by reference */ 
{ 
    char **names; 
    //somecode 
    names = malloc(num * sizeof(char*)); /* do not cast resul of malloc in C */ 
    //check 
    return names 
} 

И во второй функции, вы должны consistenly выделить память для names[i] (или *(names + i)), проверить его на NULL и скопировать строку там:

names[i] = malloc(len * sizeof(char)); 
    if (names[i] == NULL) 
    { 
     printf("Error allocating memory!\n"); //print an error message 
     return 1; //return with failure 
    } 
    strncpy(names[i], name, len); 
2

В функции getNames вы использовали неправильный указатель для проверки NULL, names[i] является *(names+i), не то же самое, как *(names[i]), также, не отбрасывают возвращаемое значение malloc «s. Нет необходимости использовать sizeof(char), это не всегда 1.

*(names + i) = (char*)malloc(len * sizeof(char)); 
if (*(names[i]) == NULL) // compare to the wrong pointer 
{ 
    printf("Error allocating memory!\n"); //print an error message 
    return 1; //return with failure 
} 
strncpy(*names, name, len); // copy to the wrong buffer 

Попробуйте следующее:

names[i] = malloc(len); 
if (names[i] == NULL) 
{ 
    printf("Error allocating memory!\n"); 
    return 1; //return with failure 
} 
strncpy(names[i], name, len); 

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

void getNum(char ***names, int *num) { 
    *names = malloc(*num * sizeof(char*)); 
} 

You будет называть его

char **names; 
getNum(&names, &num); 

Вы также можете вернуть его, выполнив char **getNum(...).

+0

Стоит отметить, что 'getNum' не будет иметь никакого эффекта * * на том, что вызывающий звонил для «имен», и, как написано, будет утечка памяти, как сито, утечка дождевой воды. – WhozCraig

+0

привет, я сделал все, что сказал, но у меня все еще есть переполнение ... во втором malloc ... –

+1

Память, выделенная 'getNum', была потеряна,' names' передан как аргумент, это только копия исходного указателя, см. Обновленный. – fluter

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