2017-04-20 8 views
-3

リストを作成するための構造を作成するプログラムを作成していますが、二重の空きまたは破損エラーが発生しています。私はリンクされたリストがより良い実装になることを知っていますが、ここで間違っていることを知りたいのです。コードは私のIDEで完全に動作しますが、UCCのターミナルでGCCを使用して実行した場合には前述のエラー が表示されます。異なるIDE上で異なるメモリ(構造体ベース)を動的に割り当てるためのプログラム

/* Implements an employee structure having name and company name 
and can take new employees, delete last employee and display entire list of employees */ 

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

// defining structure employee 
typedef struct emp 
{ 
    char name[20]; 
    char company[20]; 
}emp; 


int p = 0, size = 0; 

void create(emp *); 
void del(emp *); 
void display(emp *); 

int main(void) 
{ 
    emp *buffer = malloc(sizeof(emp)); 
    if (buffer == NULL) 
    { 
     printf("Error"); 
     exit(1); 
    } 
    int n = 0; 
    do 
    { 
     printf("The options are:\n"); 
     printf("1. Add employee\n"); 
     printf("2. Delete employee\n"); 
     printf("3. Display employee\n"); 
     printf("4. Exit\n"); 
     printf("Enter from 1 to 4:"); 
     scanf("%d",&n); 
     if (n == 1) 
     { 
      create(buffer); 
     } 
     else if (n == 2) 
     { 
      del(buffer); 
     } 
     else if (n == 3) 
     { 
      display(buffer); 
     } 
    }while(n != 4); 
    free(buffer); 
    return 0; 
} 

void create(emp *buffer) 
{ 
    size++; 
    if (p != 0) 
    { 
     buffer = realloc(buffer, size * sizeof(emp)); 
     if (buffer == NULL) 
     { 
      printf("Error"); 
      exit(1); 
     } 
    } 
    printf("Enter:"); 
    scanf("%s%s", (buffer + size - 1)->name, (buffer + size - 1)->company); 
    p++; 
} 

void del(emp *buffer) 
{ 
    // deletes only last node 
    size--; 
    buffer = realloc(buffer, size * sizeof(emp)); 
    if (buffer == NULL) 
    { 
     printf("Error"); 
     exit(1); 
    } 
} 

void display(emp *buffer) 
{ 
    int k = 0; 
    for (k = 1; k <= size; k++) 
    { 
     printf("Name:%s\n",(buffer + k - 1)->name); 
     printf("Company:%s\n",(buffer + k - 1)->company); 
    } 
} 

UPDATE: 私はvalgrindの走りとなっています以下のが、私は間違って再割り当てしています場所を正確に理解することができません。

==3322== Invalid free()/delete/delete[]/realloc() 
==3322== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3322== by 0x4008C9: create (in /home/akshay/Data/practice/a.out) 
==3322== by 0x40081C: main (in /home/akshay/Data/practice/a.out) 
==3322== Address 0x5203040 is 0 bytes inside a block of size 40 free'd 
==3322== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3322== by 0x4008C9: create (in /home/akshay/Data/practice/a.out) 
==3322== by 0x40081C: main (in /home/akshay/Data/practice/a.out) 
==3322== Block was alloc'd at 
==3322== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3322== by 0x400786: main (in /home/akshay/Data/practice/a.out) 
==3322== 
Error==3322== 
==3322== HEAP SUMMARY: 
==3322==  in use at exit: 80 bytes in 1 blocks 
==3322== total heap usage: 5 allocs, 4 frees, 2,288 bytes allocated 
==3322== 
==3322== LEAK SUMMARY: 
==3322== definitely lost: 80 bytes in 1 blocks 
==3322== indirectly lost: 0 bytes in 0 blocks 
==3322==  possibly lost: 0 bytes in 0 blocks 
==3322== still reachable: 0 bytes in 0 blocks 
==3322==   suppressed: 0 bytes in 0 blocks 
==3322== Rerun with --leak-check=full to see details of leaked memory 
==3322== 
==3322== For counts of detected and suppressed errors, rerun with: -v 
==3322== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) 
+0

[MCVE]を投稿するか、デバッガ/サニタイザを使用してください。 –

+0

引数として 'buffer'へのポインタに問題がある可能性があります。ポインタはおそらくポインタへのポインタでなければなりません:' void del(emp ** buffer) ' – Toby

+0

@Tobyしかし、ポインタへのポインタへのアクセス方法実際のデータを変更しますか?また、私が得ているエラーは、ダブルフリーまたは破損です。だから、メモリを解放することに関連している必要があります... – akshayk07

答えて

2

それにあなたが作るものは何でも変更が反映されていないので、あなたは値によってcreatedelにバッファを渡しています。したがってfreebufferの古い値を取得します。あなたは3つのオプションを持っています -

O1:あなたがsizeに対してしたようにmake buffer globalを引数として渡しません。簡単だがアドバイスはしていない。

O2:bufferdelcreateから新しい値を返します。その後doを呼び出しているとき

buffer = del(buffer); 

O3:バッファの代わりにバッファへのポインタを渡し、内部で変更します。あなたのプロトタイプは

void create(emp ** buffer); 

に変更されますそして、あなたはどこcreate内部(delも同じ)すべての*bufferを使用する必要があります。 も呼び出しがこれは少し複雑ほとんどの「正しい」ものです

create(&buffer); 

に変更されます。

この問題を理解するのに役立ちます。

+0

ありがとう、これは私の疑いを明らかにした。 – akshayk07

関連する問題