C 中的向量崩溃

Vector in C crashing

我尝试使用内存在 c 中编写一个向量 operations.Compiler 没有显示任何错误,但是如果我尝试从向量中打印一个元素,它就会崩溃。每当我尝试打印目标变量 (printf((int) destination)) 程序再次崩溃。

#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;
}

*b 不应该是指向字符串的有效指针,因此会导致崩溃。

尝试通过 printf("%d",*b);

打印

为了让它变得更好,你应该 freemalloc 分配的缓冲区。

更新

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;
}

代码的几个问题:

  1. vec->elemList = malloc(10*sizeof(typeSize)); 应该是 vec->elemList = malloc(10*typeSize);
  2. 如果你想 get 创建一个指向 int 的指针,我建议将其定义为 int* get(myvector * vec, int index) 和 return 新分配的指向 int 或在主函数中使用的指针:

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

后者也将避免内存泄漏。

  1. printf(*b); 是错误的,因为您传递的是 int 并且它期望 char* 使用 printf("%d", b); 如果 b 是 int 或 printf("%d", b);if b is aint`

  2. 您经常使用 malloc 但没有 free。在这个特定的程序中,您不会遇到内存泄漏,因为 OS 将在 main return 时回收所有内存。但是早点考虑一个函数来清除你的向量和。

基本上get中的指针处理不正确。它是按值传递的,因此创建了指针的副本,修改了副本(为此副本完成了内存分配),但是一旦退出 get 方法,原始指针就不会指向有效的内存。您必须传递指针的地址。以下是修改后的代码(注意 get 方法中目标中的双 ** )。基本上我传递了 "destination" 指针的地址而不是指针本身。此外,我修复了行 sizeof(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;
}