Ошибка сегментации с использованием strcpy

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

#include <stdio.h>
#include <string.h>

typedef struct Students {
    int q_exams;
    char **done_exams;


}Students;


int main() {

Students a;
int i;
char support[30];

printf("how many exams have you done ?\n"); 
scanf("%d",&(a.q_exams));
 a.done_exams=malloc(sizeof(char*)*a.q_exams);
if(a.done_exams==NULL)
  {
    printf("out of memory\n");
    return 0;
  }
for(i=0;i<a.q_exams;i++)
  {
    printf("Insert the name of the exam\n");
    scanf("%28s",support);
    a.done_exams[i]=malloc(strlen(support)+1);
    if(a.done_exams[i]==NULL)
    {
      printf("out of memory\n");
      return 0;
    }
    strcpy(a.done_exams[i][0],support);
    fflush(stdin);
  }

  return 0;
}

person Luca    schedule 01.01.2015    source источник
comment
зачем ты это делаешь scanf("%48s",support); char support[30]?   -  person Iharob Al Asimi    schedule 01.01.2015


Ответы (4)


Вам необходимо передать адрес начального символа в strcpy, либо так

strcpy(&a.done_exams[i][0],support);
//     ^
//  Add an ampersand

или эквивалентно так:

strcpy(a.done_exams[i] , support);
//                    ^
// Remove the second index

В настоящее время ваш код передает значение * начального символа, а не его адрес.

* Значение также не определено в то время, но это не основная причина, потому что вы вообще не должны передавать значение.

person Sergey Kalinichenko    schedule 01.01.2015

Этот код исправлен

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct Students {
    int q_exams;
    char **done_exams;
} Students;


int main()
{
    Students a;
    int i;
    char support[49];

    printf("how many exams have you done ?\n");
    scanf("%d",&(a.q_exams));

    a.done_exams = malloc(sizeof(char*) * a.q_exams);
    if(a.done_exams==NULL)
    {
        printf("out of memory\n");
        return 0;
    }

    for(i = 0 ; i < a.q_exams ; i++)
    {
        printf("Insert the name of the exam\n");
        scanf("%48s",support);

        a.done_exams[i] = malloc(strlen(support)+1);
        if(a.done_exams[i] == NULL)
        {
            printf("out of memory\n");
            return 0;
        }
        strcpy(a.done_exams[i]/*[0]*/, support);
        /*     ^                 ^- this is wrong
         *     + pass the address to the array not the first element value
         *
         * if you had warnings turned on you would have seen this
         */
        fflush(stdin);
    }

    return 0;
}

Заметь

scanf("%48s", support);

требует

char support[49];

что тоже зафиксировано в коде.

person Iharob Al Asimi    schedule 01.01.2015

См. Справочную страницу strcpy().

Первый аргумент должен иметь тип char *.

Согласно вашему коду аргумент [a.done_exams[i][0]] имеет тип char. На самом деле вам нужно передать char * [начальный адрес пункта назначения].

Измените свой код на

strcpy(a.done_exams[i],support);
person Sourav Ghosh    schedule 01.01.2015

В

strcpy(a.done_exams[i][0],support);

должно быть

strcpy(a.done_exams[i],support);

or

strcpy(&a.done_exams[i][0],support);

Я бы посоветовал всегда компилировать с включенными предупреждениями компилятора. Мой компилятор (gcc) очень хорошо выявляет проблему и сообщает вам, что именно нужно сделать, чтобы ее исправить:

test.c:37:12: warning: incompatible integer to pointer conversion passing 'char' to
              parameter of type 'char *'; take the address with & [-Wint-conversion]
    strcpy(a.done_exams[i][0],support);
           ^~~~~~~~~~~~~~~~~~
           &

P.S. Вам также не хватает некоторых #include:

#include <stdlib.h>
#include <string.h>
person NPE    schedule 01.01.2015
comment
но почему это не то же самое, что a.done_exams [i] [0]? - person Luca; 01.01.2015
comment
@Luca: Один - адрес done_exams[i][0], другой - его значение. - person NPE; 01.01.2015