-2

所以我试图实现一个简单的内存池作为大学作业的一部分,但是我遇到了在我分配的内存中存储值的麻烦。

这是我的 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);
}

每当我调用包含调用 memcpy 的行的“store_in_pool”时,就会出现问题。我不确定问题是什么,因为我确定我将正确的值传递给函数但是每次尝试运行程序时都会发生分段错误。

问题的原因可能是什么?

4

3 回答 3

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->data 永远不会被初始化。修改它的一种方法:

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。

于 2016-02-19T22:26:12.240 回答
2

由于以下原因发生分段错误:

int* a = (int*)100;

这设置a为指向地址的指针,该地址100不是可访问内存的一部分。因此,当您尝试从该地址复制时memcpy(),您会遇到错误。

如果你想a用 value 指向一个整数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()分配空间,因为它会自动将空间初始化为零。

于 2016-02-19T22:26:36.977 回答
1

改变这个:

Pool* pool = (Pool*)malloc(sizeof(Pool*));

对此:

Pool* pool = malloc(sizeof Pool);
于 2016-02-19T22:01:50.943 回答