2015-09-27 73 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返回时,操作系统将收回所有内存,因此不会收到内存泄漏。但早点想一下清除你的向量和函数的函数。