所以我试图将一个简单的内存池作为大学作业的一部分来实现,但是我已经遇到了将值存储在我已经分配的内存中的问题。
这是我的main.c文件:
#include <stdio.h>
#include "Pool.h"
int main(int argc, char** argv)
{
Pool* pool = allocate_pool(64);
printf("Pool Size: %d bytes...\n", pool->size_bytes);
int* a = (int*)100;
store_in_pool(pool, 20, sizeof(int), a);
void* ap = retrieve_from_pool(pool, 20, sizeof(int));
printf("%d\n", ap);
free_pool(pool);
return 0;
}
我的Pool.h文件:
#ifndef ASSIGNMENT_2_POOL_H
#define ASSIGNMENT_2_POOL_H
typedef struct MemoryPool
{
int size_bytes;
void* data;
} Pool;
Pool* allocate_pool(int size_bytes);
void free_pool(Pool* pool);
void store_in_pool(Pool* pool, int offset_bytes, int size_bytes, void* object);
void* retrieve_from_pool(Pool* pool, int offset_bytes, int size_bytes);
#endif
我的Pool.c文件:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "Pool.h"
Pool* allocate_pool(int size_bytes)
{
Pool* pool = (Pool*)malloc(sizeof(Pool*));
pool->size_bytes = size_bytes;
pool->data = malloc(size_bytes);
int i = 0;
while(i < pool->size_bytes)
{
void* temp = (int*)pool->data + i++;
temp = 0;
}
return pool;
}
void free_pool(Pool* pool)
{
free(pool->data);
free(pool);
}
void store_in_pool(Pool* pool, int offset_bytes, int size_bytes, void* object)
{
memcpy((void*)((char*)pool->data + offset_bytes), object, size_bytes);
}
void* retrieve_from_pool(Pool* pool, int offset_bytes, int size_bytes)
{
return (void*)((char*)pool->data + offset_bytes);
}
只要我打电话给&#39; store_in_pool&#39;就会出现问题。其中包含一个调用memcpy的行。我不确定问题是什么,因为我确定我将正确的值传递给函数,但是每次尝试运行程序时都会发生分段错误。
问题可能是什么原因?
答案 0 :(得分:2)
问题在于:
Pool* pool = (Pool*)malloc(sizeof(Pool*));
在32位系统上sizeof(Pool *)== 4。这是因为Pool *参数表示您需要指向Pool的指针大小。指针大小是恒定的(32位为4位,64位为8位)。它应该是:
Pool* pool = (Pool*)malloc(sizeof(Pool));
在这种情况下,Pool结构的大小将被发送到malloc。我在你的代码中注意到的另一件事。它本身并不是一个错误,但它是一个零效果的代码:
while(i < pool->size_bytes)
{
void* temp = (int*)pool->data + i++;
temp = 0;
}
您正在将临时指针设置为NULL,实际上,不是将其指向的变量设置为0.这意味着您的pool-&gt;数据永远不会被初始化。修改它的一种方法:
while(i < pool->size_bytes)
{
char* temp = (char*)pool->data + i++;
*temp = 0;
}
或者简单地说:
memset(pool->data, 0, pool->size_bytes);
或者只是在源代码中捕获它并删除初始化代码,如果您只需要初始化为0:
pool->data = calloc(1, pool->size_bytes);
在这种情况下,calloc将所有字节设置为0。
答案 1 :(得分:2)
由于这个原因,分段错误正在发生:
int* a = (int*)100;
这会将a
设置为指向地址100
的指针,该地址不是可访问内存的一部分。因此,当您尝试使用memcpy()
从该地址进行复制时,您会遇到错误。
如果您希望a
指向值为100
的整数,则正确的方法是:
int aval = 100;
int *a = &aval;
您还需要修改malloc()
中allocate_pool
的调用方式:
Pool* pool = malloc(sizeof Pool);
您的代码只是为指针分配足够的空间,而不是整个Pool
结构。
while
循环似乎试图将data
初始化为零也是错误的。您只需使用memset
:
memset(pool->data, 0, size_bytes);
您也可以使用calloc()
代替malloc()
来分配空间,因为它会自动将空间初始化为零。
答案 2 :(得分:1)
改变这个:
Pool* pool = (Pool*)malloc(sizeof(Pool*));
到此:
Pool* pool = malloc(sizeof Pool);