2016-02-28 3 views
-4

Итак, для моего задания у меня есть следующее, за которым следуют некоторые инструкции, что делать с кодом. Я должен реализовать систему распределения памяти, которая позволяет пользователям читать и записывать типы данных низкого уровня. Первая часть assingment говорит «Реализовать следующие API:»Что означает «реализовать следующий API» в отношении программирования на C?

/* Allocate a memory pool of size n bytes from system memory (i.e., via malloc()) and return a pointer to the filled data Pool structure */ 

Pool* allocatePool(int n); 

/* Free a memory pool allocated through allocatePool(int) */ 

void freePool(Pool* pool); 

/* Store an arbitrary object of size n bytes at location offset within the pool */ 

void store(Pool* pool, int offset, int size, void *object); 

/* Retrieve an arbitrary object of size n bytes from a location offset within the pool */ 

void *retrieve(Pool* pool, int offset, int size); 


You must implement a struct called Pool, but you may define it as you like. The following is suggested as a starting point: 

/* _POOL - pool 
* int size - the size of the pool in bytes 
* void* ipPool - pointer to memory malloc'd by the operating system 
*/ 

typedef struct _POOL 
{ 
    int size; 
    void* memory; 
} Pool; 

Любая помощь будет очень ценится.

+3

Чтобы вы определили определения для вышеперечисленных функций, они будут делать то, что предлагают имена и комментарии. – pikkewyn

+0

@pikkewyn, поэтому мне нужно создать программу, чтобы эти ссылки (которые выполняют то, что указаны в комментариях) функционируют по назначению? – Gherkin

+0

См. Https://en.wikipedia.org/wiki/Application_programming_interface – markgz

ответ

1

В дополнение к комментариям, как вы должны сделать вывод, API, используемый в отношении вашего назначения, представляет собой просто набор функций и структур данных, доступных для использования. (примечание: в C, стиль обычно избегает использования CamelCase и ЗАГЛАВНЫМИ БУКВАМИ для переменных и имен структуры, так что я буду делать то же ниже.)

В API вы получили предоставляет четыре функции allocatepool , freepool, store и retrieve вместе с одним pool datastruct. (примечания: нет необходимости в различные struct и typedef тегов, поскольку они занимают разные пространства имен и не буду противоречить другу другу.) Учитывая Вашу структуру:

typedef struct pool { /* note: struct tag and typedef are not */ 
    int size;   /* required to be different (_pool, pool) */ 
    void* memory; 
} pool; 

при выделении памяти для этого struct, необходимо выделить память для struct, и выделить хранилище для memory. Вы можете использовать либо malloc, либо calloc (который будет выделять и обнулять всю новую память). Как минимум, распределение потребуется:

pool *p = malloc (sizeof *p); 
p->memory = malloc (n);  /* for a pool of size n */ 

Однако, в любое время выделения памяти, вы должны убедиться, что действительный указатель на новый блок памяти был возвращен. Так что для вашей allocatepool функции, вы бы что-то подобное:

pool *allocatepool (int n) 
{ 
    if (n <= 0) { 
     fprintf (stderr, "error: invalid allocation size.\n"); 
     return NULL; 
    } 
    pool *p = malloc (sizeof *p); /* allocate struct */ 
    if (!p) { /* validate */ 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return NULL; 
    } 

    p->size = n; 
    if (!(p->memory = malloc (n))) {/* allocate pool */ 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return NULL; 
    } 

    return p; 
} 

Чтобы освободить память с freepool, вы, по сути освобождая объекты, которые вы выделили, в обратном порядке. Если есть вероятность, что этот объект может быть освобожден в какой-либо промежуточной точке вашей программы, хорошо проверить, что у вас есть действительный адрес перед вызовом free. Например, вы freepool функция может выглядеть следующим образом:

void freepool (pool *p) 
{ 
    if (!p) return; /* validate pool address */ 

    if (p->memory) 
     free (p->memory); /* free memory pool */ 

    free (p); /* free struct */ 
} 

Для вашего store функции вы хотите проверить size и offset не превышает допустимое хранилище. Так как вы захватили size распределения в качестве члена вашей структуры, вам нужно сравнить только запрошенные size и offset с членом вашей организации size. Например:

void store (pool *p, int offset, int size, void *object) 
{ 
    if (!p) { /* validate pool address */ 
     fprintf (stderr, "error: invalid parameter 'p'.\n"); 
     return; 
    } 
    if (size + offset > p->size) { /* validate request */ 
     fprintf (stderr, "error: offset + size > p->size\n"); 
     return; 
    } 
    memcpy (p + offset, object, size); /* copy object to pool */ 
} 

Наконец, ваш retrieve функция, по существу, делает в обратном, что ваша store функция делается для того, чтобы восстановить сохраненную информацию из того же offset, к которому она была сохранена.Однако, поскольку вам нужно вернуть указатель на новый объект, вам нужно будет выделить новый объект в пределах retrieve (в отличие от простого возврата указателя на смещение в исходном пуле памяти, где хранятся данные.) должен отслеживать возвращаемый адрес, чтобы он мог быть освобожден, когда он больше не требуется. Например:

void *retrieve (pool *p, int offset, int size) 
{ 
    if (!p) return NULL; /* validate pool address */ 

    void *obj = malloc (size); /* allocate obj */ 
    if (!obj) { /* validate */ 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return NULL; 
    } 
    /* copy and return */ 
    return memcpy (obj, p + offset, size); 
} 

Вы можете поместить все кусочки головоломки вместе с небольшой пример программы:

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

enum { SIZE = 10 };  /* enum defining a constant SIZE as 10 */ 

typedef struct pool { /* note: struct tag and typedef are not */ 
    int size;   /* required to be different (_pool, pool) */ 
    void* memory; 
} pool; 

pool *allocatepool (int n); /* function declarations */ 
void freepool (pool *p); 
void store (pool *p, int offset, int size, void *object); 
void *retrieve (pool *p, int offset, int size); 

int main (void) { 

    size_t sz = SIZE;  /* declare/initialize variables */ 
    char str[] = "hello"; 
    pool *p = NULL, *obj = NULL; 

    p = allocatepool (2 * sz);  /* allocate p */ 

    store (p, sz/2, sizeof str, str); /* store str in p's pool at sz/2 */ 

    if (!(obj = retrieve (p, sz/2, sizeof str))) { /* retrieve in obj */ 
     fprintf (stderr, "error: retrieve failed.\n"); 
     return 1; 
    } 

    printf ("Pool API says:\n %s world.\n", (char *)obj); /* use obj */ 

    free (obj);  /* free allocated memory */ 
    freepool (p); 

    return 0; 
} 

/* function definitions below */ 

Запуск программы будет производить следующие действия:

Выходной

$ ./bin/pool 
Pool API says: 
hello world. 

Ошибка/проверка памяти Ошибка

Каждый раз, когда вы распределяете память динамически, вам необходимо (1) сохранить указатель на начальный адрес памяти, поэтому он может быть освобожден (2), когда он больше не нужен. Чтобы проверить использование вашей памяти, запустите программу, хотя проверите память, например valgrind на Linux (на всех платформах есть аналогичные средства проверки памяти). Это просто сделать, например.

$ valgrind ./bin/pool 
==16664== Memcheck, a memory error detector 
==16664== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==16664== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info 
==16664== Command: ./bin/pool 
==16664== 
Pool API says: 
hello world. 
==16664== 
==16664== HEAP SUMMARY: 
==16664==  in use at exit: 0 bytes in 0 blocks 
==16664== total heap usage: 3 allocs, 3 frees, 42 bytes allocated 
==16664== 
==16664== All heap blocks were freed -- no leaks are possible 
==16664== 
==16664== For counts of detected and suppressed errors, rerun with: -v 
==16664== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1) 

Ознакомьтесь с примерами и примерами определений функций. Дело в том, чтобы продумать, какие проверки и проверки необходимы для работы вашего кода без чтения или записи за пределами выделенного пространства памяти. Это минимальные требования.

Смежные вопросы