2011-10-22 16 views
0

動的に変化する構造体でポインタを動かすことに問題があります。 mallocでメモリを増やすことができるコードを作成しましたが、これは機能しているようです。 私は、構造に追加する方法、メモリを解放する方法、構造から構造に移動してすべての項目を印刷する方法について問題を抱えています。mallocと動的に変化する構造体でフリー

私はその値からセグメンテーション違反を取得し、私は構造体に追加すると追加して印刷(仕事にそこにいないようです削除機能、セグメンテーションフォールト)をテストするために

をしようとして、構造体を印刷しています私が追加しました。最初の構造体から次の構造体に正しく移動しているかどうかはわかりません。

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

/******************************************** 
Creates more memory for size (strut * rec+1) 
*********************************************/ 

employee *create(int record){ 
employee *new_employee = malloc(sizeof(employee) * (record+1)); 

return new_employee;  
} 

/******************************************** 
Copies the data from one structure to a new structure with 
size "structure" multipled by rec+1 
***********************************************/ 
employee *copy(employee *data, int record){ 
    employee *new_employee = create(record); 
int i; 
    for(i = 0; i<record;i++){ 
     new_employee->first = data->first; 
     new_employee->last = data->last; 
     new_employee->start_date = data->start_date; 
     new_employee->sal = data->sal; 
     data++; 
    } 
    /******************** 
    Needs to free the old struct 
    *********************/ 
    //deleteData(data, record); 

return new_employee; 
} 
/******************************************** 
Function prints everything in the struct 
*********************************************/ 
void printStruct(employee *data, int record){ 
int i; 

    for(i = 0; i<record; i++){ 
     printf("\nEntry: %d\n", i+1);   
     printf("The employee's name is %s %s\n", data->first, data->last); 
     printf("The employee was hired on: %s\n", data->start_date); 
     printf("The employee make $%f\n\n", data->sal); 
     data++;  
    } 
} 
/****************************************** 
Function frees the old data base 
*******************************************/ 
void deleteData(employee *data, int record){ 
int i; 
    for(i = 0; i<record; i++){ 
     free(data->first); 
     free(data->last); 
     free(data->start_date); 
     data++; 
    } 
    free(data); 
} 
/****************************************** 
Adds an employee to the new structure 
*******************************************/ 
employee *add(employee *data,char *fname, char *lname, char *date, float salary, int record){ 
employee *employeeDB = create(record); 
employeeDB = copy(data, record); 
int i; 
    employeeDB++; 
    employeeDB->first = fname; 
    employeeDB->last = lname; 
    employeeDB->start_date = date; 
    employeeDB->sal = salary; 

return employeeDB; 
} 




/************************** 
Starts of the main function 
***************************/ 

int main(void){ 
    //Keeps track of the number of records that are in the structure 
int rec = 0; 
    //Keeps the number of accesses to the structure. Even with the one entry the structure has not been accessed. 
int acc = 0; 
    //Holds the input information for the menu 
int input; 
    //holds the information for inputing user first name 
char *fname; 
    //holds the information for inputing user last name 
char *lname; 
    //holds the information for for the startdate 
char *start; 
    //holds the information for the salary; 
float sal; 
/********************************* 
This next section adds an employee to the record 

************************************/ 
//This creates the first entry to the dynamic structure. 
employee *first_employee = create(rec); 
first_employee->first = "FIRST"; 
first_employee->last = "LAST"; 
first_employee->start_date = "June-20th-2006"; 
first_employee->sal = 55555.55; 
//increase the number of records  
rec = rec+1; 

employee *new_employeeDB = add(first_employee, "fname", "lname", "JUNE-20th-2010", 55555.55, rec); 
rec = rec + 1; 
printStruct(new_employeeDB, rec); 


printf("%d\n", (sizeof(employee)* rec)); 


} 
+0

代わりに ''データをコピーする(...){...}のための、あなたは 'のmemcpy(new_employeeだけで行うことができます、data、record * sizeof(従業員)); '。また、配列インデックスとオブジェクトサイズには 'int'の代わりに' size_t'を使います。 –

+0

memcpyは新しいメモリをmallocしますか? – jenglee

+0

いいえ、データをあるチャンクから別のチャンクにコピーするだけです。 –

答えて

0

最初の問題:OK ...従業員の種類の宣言は含まれていませんでした。 最初と最後がcharポインタとして宣言されていると思いますが、これはエラーです。 固定サイズのchar配列である必要があります。これは決して動作しません。 文字列の最大長を選択し、このような構造体を宣言します。

typedef struct 
{ 
    char name[50]; 
    char surname[50]; 
    .... 
} employee; 

前の投稿:

さて、私は多くの事を実現するためのこの方法を好きではない認めなければなりません。 私はより安定したアプローチを使用します。

まず第一に、それは単なるアイテムリストであるため、二重リンクリストを使用することができます。 これにより、O(1)の複雑さを持つ要素を追加したり削除したりすることができます。確かに良い。

これにより、すべてのアイテムを最初から最後まで繰り返すこともできます。

これを行うには、よりOOP指向のアプローチを使用します:)私は知っている、私たちはCですが、このアイデアを聞いてください。すべての項目を反復する

typedef struct 
{ 
    MyList* OwnerList; 
    Employee* Previous; 
    Employee* Next; 

    char name[50]; 
    int age; 
} Employee; 

typedef struct 
{ 
    Employee* First; 
    Employee* Last; 
    int Count; 
} MyList; 

MyList* AllocList() { return calloc(sizeof(MyList), 1); } 

void DeleteList(MyList* list) 
{ 
    Employee* current; 
    Employee* next; 
    for (current = list->First; current != NULL; current = next) 
    { 
     next = current->Next; 
     free(current); 
    } 
    free(list); 
} 

int GetCount(const MyList* list) 
{ 
    return list->Count; 
} 

Employee* AddAmployee(MyList* list) 
{ 
    Employee* result = calloc(sizeof(Employee), 1); 
    Employee* last = list->Last; 
    if (last != null) 
     last->Next = result; 
    else 
     list->First = result; 
    result->Previous = last; 
    list->Last = result; 
    ++list->Count; 
    result->OwnerList = list; 
    return result; 
} 

void RemoveEmployee(Employee* employee) 
{ 
    /* i leave removal for you as exercise :) look for doubly linked list */ 
    free(employee); 
} 

は、単純です:

Employee* current; 
for (current = list->First; current != null; current = current->Next) 
    printf("%s %d\n", current->name, current->age); 
+0

このようにしてポインタを最初の構造体から次の構造体に移動するには、実際の構造体の – jenglee

+0

ああ、確かに。申し訳ありません:) –

+0

これはC++ではないので、 'malloc'をキャストする必要はなく、' struct'キーワードなしで名前を使用するには 'typedef struct {} name'する必要があります。 –

0

従業員のfirst、last、およびstart_date属性を割り当てるためにmallocを使用していません。そのため、deleteDataのポインタをフリーで呼び出すと、メモリが壊れてしまいます。また、リンクされたリストやその他のデータ構造(配列など)を使用して従業員のレコードを保持することも検討し、より洗練されたインターフェースを持つことができます。

+0

私はリンクリストを使用したいと思っていますが、このような要求には私にこのような要求があります。私はあなたが構造体のmallocで構造体のすべてをmallocすると思った。 – jenglee

+0

構造体内のポインタを解放する必要はなく、ポインタ自体に格納されているデータは静的に割り当てられます。データ(first_name、last_nameなど)を動的に割り当てた場合、ポインタはフリーでなければなりません。 – bejar37

関連する問題