2014-08-27 3 views
2

Я изучаю некоторые новые вещи и зацикливаюсь на простой операции strcpy. Я не понимаю, почему в первый раз, когда я печатаю работы, но второй раз это не так.Strcpy Segmentation Fault C

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

int main() 
{ 
    char *name; 
    char *altname; 

    name=(char *)malloc(60*sizeof(char)); 
    name="Hello World!"; 
    altname=name; 
    printf("%s \n", altname); 
    altname=NULL; 
    strcpy(altname,name); 
    printf("%s \n", altname); 
    return 1; 
} 
+1

Вы не выделяете больше памяти для altname/name. –

ответ

4

Вам нужно выделить память для altname:

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

int main() 
{ 
    char *name; 
    char *altname; 

    name=(char *)malloc(60*sizeof(char)); 
    name="Hello World!"; 
    altname=name; 
    printf("%s \n", altname); 
    altname=NULL; 
    // allocate memory, so strcpy has space to write on ;) 
    altname=(char *)malloc(60*sizeof(char)); 
    strcpy(altname,name); 
    printf("%s \n", altname); 
    return 1; 
} 
2

В первый раз, вы делаете altname точку в том же месте, name. Это нормально, потому что name указывает на действительный char* (первый элемент OFTHE "Hello World!" буквального)

// both point to beginning of "Hello World!" literal 
altname=name; 

Второй раз, вы пытаетесь скопировать данные повернутыми на name в месте, на который указывает altname, который на этом этапе указывает на NULL. Поэтому вы пытаетесь записать в NULL, который является источником ошибки.

strncpy требует, чтобы буфер назначения был доступен для записи и был достаточно большим, чтобы скопировать данные исходной строки. Вам нужно сделать altname, указывая на буфер, который достаточно велик для содержимого строки name указывает на.

altname = (char*)malloc(60*strlen(name)+1); // +1 for nul terminator 
strcpy(altname, name); 

Также обратите внимание, что при установке name = "Hello World!", вы утечка памяти он первоначально указал на. Вам нужно освободить, что первый:

free(name); 
name = "Hello World!"; 
+2

Нет, на самом деле, он устанавливает altname = NULL и пытается скопировать туда, так что я бы сказал, что исключение в виде исключающего указателя. – Greycon

+1

@ Greycon К сожалению, я пропустил NULL. Исправлена. – juanchopanza

6

Проблемы начинаются здесь:

name=(char *)malloc(60*sizeof(char)); 
name="Hello World!"; 

Вы заменили значение, возвращенное malloc с строковый литерал.

  1. Вы утечка памяти (так как вы не можете восстановить значение указателя, возвращаемого malloc). Все вызовы malloc соответствуют соответствующему вызову free. Поскольку значение этого указателя ушло, возможность вызова free с указанным значением указателя также исчезла.

  2. Далее вы пишете указатель NULL, что является неопределенным поведением (которое в вашем случае вызвало ошибку сегментации).

+1

@juanchopanza - Я внес изменения в свой ответ. – PaulMcKenzie

1

Вы пытаетесь присвоить значение altname, у которого нет свободного места. Сначала выделите память на altname, затем назначьте

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

int main() 
{ 
    char *name; 
    char *altname; 

    name=(char *)malloc(60*sizeof(char)); 
    name="Hello World!"; 
    altname=name; 
    printf("%s \n", altname); 
    altname=NULL; 
    altname=(char *)malloc(sizeof(name)); // allocate memory 
    strcpy(altname,name);     // Now assign 
    printf("%s \n", altname); 
    return 1; 
}