Luca
Luca

Reputation: 55

Segmentation fault using strcpy

I have some troubles when using strcpy to copy an array of string inside a double pointer with allocated memory, but i can't understand why i get segmentation fault even if i have previously allocated memory. Here is the code:

#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;
}

Upvotes: 2

Views: 694

Answers (4)

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53026

This code is fixed

#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;
}

notice that

scanf("%48s", support);

requires

char support[49];

which is also fixed in the code.

Upvotes: 1

NPE
NPE

Reputation: 500893

The

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

should be

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

or

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

My advice would be to always compile with compiler warnings turned on. My compiler (gcc) does a very good job of catching the problem and telling you exactly what needs to be done to fix it:

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. You are also missing some #includes:

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

Upvotes: 0

Sourav Ghosh
Sourav Ghosh

Reputation: 134396

See the man page of strcpy().

The first argument should be of type char *.

As per your code, the argument [a.done_exams[i][0]] is of type char. You need to pass a char * [starting address of the destination] actually.

Change your code to

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

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727047

You need to pass an address of the initial character to strcpy, either like this

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

or equivalently like this:

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

Currently, your code passes the value* of the initial character, rather than its address.

* The value is undefined at the time as well, but it is not the primary cause, because you should not be passing value at all.

Upvotes: 1

Related Questions