2012-12-28 1 views
2

Я программировал некоторое время, но я новичок в C. У меня есть реализация связанного списка в ansi C, которую мне нужно протестировать. Я сузил проблему до проблемы с недопустимой записью. Я побежал код через Valgrind и получил следующий результат:Invalid Write with strcpy

==18131== Invalid write of size 1 
==18131== at 0x4C2C0CC: __GI_strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64 linux.so) 
==18131== by 0x40089B: main (in /home/btm7984/hw3/TestList) 
==18131== Address 0x51f1388 is 0 bytes after a block of size 8 alloc'd 
==18131== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==18131== by 0x400880: main (in /home/btm7984/hw3/TestList) 
==18131== 
==18131== Invalid write of size 1 
==18131== at 0x4C2C0DF: __GI_strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==18131== by 0x40089B: main (in /home/btm7984/hw3/TestList) 
==18131== Address 0x51f138e is 6 bytes after a block of size 8 alloc'd 
==18131== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==18131== by 0x400880: main (in /home/btm7984/hw3/TestList) 
==18131== 
--18131-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting 
--18131-- si_code=1; Faulting address: 0x6D4FCAA; sp: 0x402bdae00 

Все, что я могу определить, из этого является то, что я выделять что-то неправильно. Я думаю, что это должно быть с моей строгой линией. Я действительно не знаю, как подойти к этому вопросу. Ниже следует мое использование интерфейса LinkedLists. InitLinkedLists, AddToBackOfList и DestroyList определены в этом интерфейсе.

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

int main(int argc, char *argv[]) { 

    FILE *fp; 
    char tmpString[100]; 
    LinkedLists *ListPtr = malloc(sizeof(LinkedLists)); 
    ElementStructs *DataPtr; 
    LinkedListNodes* curr = malloc(sizeof(LinkedListNodes)); 
    int counter = 0; 
    int Done = 0; 

    InitLinkedList(ListPtr); 
    fp = fopen(argv[1], "r"); 
    if (!fp){ 
    fprintf(stderr,"%s Cannot open file %s\n", argv[0], argv[1]); 
    exit(1); 
    } 
    do{ 
    fscanf(fp,"%s",tmpString); 
    if (!feof(fp)) { 
     DataPtr = malloc(sizeof(DataPtr)); 
     printf("%d %d : %d\n",counter,(int)strlen(DataPtr->str),(int)strlen(tmpString)); 
     strcpy(DataPtr->str,tmpString); 
     DataPtr->index=counter; 
     AddToBackOfLinkedList(ListPtr, DataPtr); 
     counter++; 
     Done = 1; 
    } else { 
     Done = 0; 
    } 
    }while (Done); 

В заключение, я думаю, что strcpy вызывает недопустимую запись, и я не знаю почему.

Любая помощь была бы принята с благодарностью. Заранее спасибо.

EDIT: ElementStructs определяется следующим образом:

typedef struct ElementStructs 
    { 
    /* Application Specific Definitions */ 
    int index; 
    char str[100]; 
    } ElementStructs; 
+0

Как 'ElementStructs' определенные? – cnicutar

+3

'p = malloc (sizeof p)' всегда неверно. – melpomene

+0

typedef struct ElementStructs { /* Специфические определения приложения */ int index; char str [100]; } ElementStructs; – user1935333

ответ

3

Проблема заключается в этом утверждении:

DataPtr = malloc(sizeof(DataPtr)); 

Вы выделить достаточно только памяти для хранения указателя, а не полный STRUCT.

Вы должны выделить с помощью:

DatapPtr = malloc(sizeof(ElementStructs)); 

или, как описано в комментариях (WhozCraig):

DatapPtr = malloc(sizeof(*DataPtr)); 
+0

Спасибо. Сейчас я работаю. Это была отличная помощь – user1935333