2015-09-27 35 views
0

我試圖用c編寫一個使用內存操作的向量。編譯器顯示沒有錯誤,但如果我嘗試從向量打印元素,它只會崩潰。每當我嘗試打印目標變量(printf((int)destination))程序再次崩潰。在C崩潰的向量

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

typedef struct{ 
    void* elemList; 
    int elemSize; 
    int maxSize; 
    int curSize; 
}myvector; 

void initVec(myvector * vec, int typeSize){ 
    vec->curSize = 0; 
    vec->maxSize = 10; 
    vec->elemSize =typeSize; 
    vec->elemList = malloc(10*sizeof(typeSize)); 
} 
void add(myvector * vec, void* elem){ 
    if(vec->curSize >= vec->maxSize){ 
     vec->elemList = realloc(vec->elemList, vec->maxSize*2); 
    } 
    memcpy(&vec->elemList[vec->curSize],elem,vec->elemSize); 
} 
void get(myvector * vec, int index, void* destination){ 
    if(index > vec->curSize || index < 0){ 
     printf("Invalid Index"); 
     return; 
    } 
    destination = malloc(vec->elemSize); 
    memcpy(destination,&vec->elemList[index], vec->elemSize); 
} 
int main() 
{ 
    myvector newVec; 
    initVec(&newVec,sizeof(int)); 
    int a = 5; 
    add(&newVec,&a); 
    int* b; 
    get(&newVec,0,b); 
    printf(*b);//this is where the program crashes 
    return 0; 
} 

回答

1

基本上在指針得到沒有正確處理。它被按值傳遞,因此指針的副本被創建,副本被修改(爲該副本完成內存分配),但是一旦您退出get方法,原始指針就不會指向有效的內存。你必須傳遞指針的地址。以下是一個修改後的代碼(注意在得到方法在目標中的雙**)。基本上我傳遞的是「目標」指針的地址,而不是指針本身。此外,我修復了lineof(typeSize)..它只應該是typeSize,因爲您已經使用sizeof運算符調用了initVec方法。

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

typedef struct{ 
    void* elemList; 
    int elemSize; 
    int maxSize; 
    int curSize; 
}myvector; 

void initVec(myvector * vec, int typeSize){ 
    vec->curSize = 0; 
    vec->maxSize = 10; 
    vec->elemSize = typeSize; 
    vec->elemList = malloc(vec->maxSize*typeSize); 
} 
void add(myvector * vec, void* elem){ 
    if(vec->curSize >= vec->maxSize) 
    { 
     vec->elemList = realloc(vec->elemList, vec->maxSize*2); 
    } 
    memcpy(&vec->elemList[vec->curSize], elem, vec->elemSize); 
    vec->curSize++; 
} 
void get(myvector * vec, int index, void** destination){ 
    if(index > vec->curSize || index < 0) 
    { 
     printf("Invalid Index"); 
     return; 
    } 
    *destination = malloc(vec->elemSize); 
    memcpy(*destination, &vec->elemList[index], vec->elemSize); 
} 
int main() 
{ 
    myvector newVec; 
    initVec(&newVec,sizeof(int)); 
    int a = 5; 
    add(&newVec,&a); 
    int* b; 
    get(&newVec, 0, &b); 
    printf("value of b is %d\n", *b); // This works correctly now 
    return 0; 
} 
0

*b不應該是一個有效的字符串指針,所以會導致崩潰。

嘗試通過printf("%d",*b);

打印出來,使之更好,你應該freemalloc分配的緩衝區。

UPDATE

get功能是錯誤的,因爲它扔掉分配給destination

get功能和main功能緩衝區應該是這樣的:

void get(myvector * vec, int index, void** destination){ 
    if(index > vec->curSize || index < 0){ 
     printf("Invalid Index"); 
     return; 
    } 
    *destination = malloc(vec->elemSize); 
    memcpy(*destination,&vec->elemList[index], vec->elemSize); 
} 
int main() 
{ 
    myvector newVec; 
    initVec(&newVec,sizeof(int)); 
    int a = 5; 
    add(&newVec,&a); 
    int* b; 
    get(&newVec,0,&b); 
    printf("%d",*b);//this is where the program crashes 
    return 0; 
} 

但是,這仍然給我的分割錯誤。我正在嘗試。

更新2

你應該考慮每個元素的大小。
您還忘記了add函數中的尺寸信息。
如果我們不關心內存泄漏,此代碼應該可以工作。

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

typedef struct{ 
    void* elemList; 
    int elemSize; 
    int maxSize; 
    int curSize; 
}myvector; 

void initVec(myvector * vec, int typeSize){ 
    vec->curSize = 0; 
    vec->maxSize = 10; 
    vec->elemSize =typeSize; 
    vec->elemList = malloc(vec->maxSize*vec->elemSize); 
} 
void add(myvector * vec, void* elem){ 
    if(vec->curSize >= vec->maxSize){ 
     vec->elemList = realloc(vec->elemList, vec->elemSize * vec->maxSize*2); 
     vec->maxSize *= 2; 
    } 
    memcpy(vec->elemList + vec->curSize * vec->elemSize,elem,vec->elemSize); 
    vec->curSize++; 
} 
void get(myvector * vec, int index, void** destination){ 
    if(index >= vec->curSize || index < 0){ 
     printf("Invalid Index"); 
     return; 
    } 
    *destination = malloc(vec->elemSize); 
    memcpy(*destination,vec->elemList + index * vec->elemSize, vec->elemSize); 
} 
int main() 
{ 
    myvector newVec; 
    initVec(&newVec,sizeof(int)); 
    int a = 5; 
    add(&newVec,&a); 
    int* b; 
    get(&newVec,0,(void**)&b); 
    printf("%d",*b); 
    return 0; 
} 
+0

這仍然是一樣的... –

+0

我明白我所做的指針算術錯誤,但爲什麼目標變量會改變?我的意思是變量b不應該指向另一個方向嗎? –

+0

這裏「目標變量」和「另一個方向」是什麼意思? – MikeCAT

0

一對夫婦與代碼問題:

  1. vec->elemList = malloc(10*sizeof(typeSize));應該vec->elemList = malloc(10*typeSize);
  2. 如果您想get創建一個指向int我會建議,要麼定義它像int* get(myvector * vec, int index)和回報一個新分配的指針int或在主要功能用途:

    int b; 
    get(&newVec, 0, &b); 
    

後者也將避免內存泄漏。

  • printf(*b);是錯誤的,因爲要傳遞一個int並期望一個char*兼用printf("%d", b);如果b爲int或輸出( 「%d」,B); if b is a INT`

  • 您使用malloc了很多,但沒有free。在這個特定的程序中,當main返回時,操作系統將收回所有內存,因此不會收到內存泄漏。但早點想一下清除你的向量和函數的函數。