fehler bei memcpy



  • //////////////////////////////// MemoryManager.h
    #ifndef MEMORYMANAGER_H
    #define MEMORYMANAGER_H
    
    typedef unsigned char uint8_t;
    typedef unsigned short uint16_t;
    typedef unsigned int uint32_t;
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define offsetof(struct_type, member) \
    	(size_t) &(((struct_type *)0)->member)
    
    typedef struct MemoryUnit
    {
    	uint8_t mem_used_flag;
    	uint8_t buffer[1];
    }MemoryUnit;
    
    typedef struct MemoryManager 
    {
    	MemoryUnit *memory_array;
    	uint32_t num_of_units;
    }MemoryManager;
    
    uint32_t CreateMemoryManager(struct MemoryManager **mmhandle, uint32_t unit_size, uint32_t num_of_units);
    uint8_t *AllocateMemoryUnit(struct MemoryManager *mmhandle);
    void FreeMemoryUnit(struct MemoryManager *mmhandle, uint8_t *unitptr);
    uint32_t DestroyMemoryManager(struct MemoryManager *mmhandle);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    
    //////////////////////////////// MemoryManager.c
    #include "MemoryManager.h"
    #include <stdlib.h>
    
    uint32_t CreateMemoryManager(struct MemoryManager **mmhandle, uint32_t unit_size, uint32_t num_of_units)
    {
    	(*mmhandle) = (MemoryManager *)malloc( sizeof(MemoryManager) );
    	(*mmhandle)->num_of_units = num_of_units;
    	(*mmhandle)->memory_array = (MemoryUnit *)malloc( (sizeof(uint8_t) + unit_size) * num_of_units );
    	memset((*mmhandle)->memory_array, 0, (sizeof(uint8_t) + unit_size) * num_of_units );
    
    	return 1;
    }
    
    uint8_t *AllocateMemoryUnit(struct MemoryManager *mmhandle)
    {
    	uint32_t i = 0;
    
    	for(i = 0; i < mmhandle->num_of_units; i++) {
    		if(mmhandle->memory_array[i].mem_used_flag == 0) {
    			mmhandle->memory_array[i].mem_used_flag = 1;
    			return mmhandle->memory_array[i].buffer;
    		}
    	}
    
    	return 0;
    }
    
    void FreeMemoryUnit(struct MemoryManager *mmhandle, uint8_t *unitptr)
    {
    	struct MemoryUnit *unit;
    	uint8_t offset = 0;
    
    	offset = offsetof(struct MemoryUnit, /*mmhandle->memory_array->*/buffer);
    	unitptr -= offset;
    
    	unit = (struct MemoryUnit*)unitptr;
    	unit->mem_used_flag = 0;
    
    	return 0;
    }
    
    uint32_t DestroyMemoryManager(struct MemoryManager *mmhandle)
    {
    	free(mmhandle->memory_array);
    	free(mmhandle);
    
    	return 1;
    }
    
    /////////////////////////////////////// main.c
    #include "MemoryManager.h"
    
    int main() 
    {
        MemoryManager *mmhandle = NULL;
        uint8_t *memptr[2000];
        uint8_t sector[512];
        uint32_t i = 0;
    
        for(i = 0; i < 512; i++) {
    	    sector[i] = i;
        }
        CreateMemoryManager(&mmhandle, 512, 2000);
        for(i = 0; i < 2000; i++) {
    	    memptr[i] = AllocateMemoryUnit(mmhandle);
    	    memcpy(memptr[i], sector, sizeof(sector));
        }
    
        for(i = 0; i < 2000; i++) {
    	    FreeMemoryUnit(mmhandle, memptr[i]);
        }
    }
    

    warum gibts hier nen fehler nach i == 8?

    for(i = 0; i < 2000; i++) {
    	    memptr[i] = AllocateMemoryUnit(mmhandle);
    	    memcpy(memptr[i], sector, sizeof(sector));  <--- problem
        }
    


  • michl22 schrieb:

    warum gibts hier nen fehler nach i == 8?

    for(i = 0; i < 2000; i++) {
    	    memptr[i] = AllocateMemoryUnit(mmhandle);
    	    memcpy(memptr[i], sector, sizeof(sector));  <--- problem
        }
    

    welchen inhalt hat denn 'memptr[8]'?
    vielleicht hat 'AllocateMemoryUnit' bei 8 nichts alloziert?
    ein fall für'n debugger, oder du spickst den code mit 'printfs' um debugausgaben zu bekommen...
    🙂



  • der fehler liegt in:

    uint8_t *AllocateMemoryUnit(struct MemoryManager *mmhandle)
    {
        uint32_t i = 0;
    
        for(i = 0; i < mmhandle->num_of_units; i++) {
            if(mmhandle->memory_array[i].mem_used_flag == 0) {
                mmhandle->memory_array[i].mem_used_flag = 1;
                return mmhandle->memory_array[i].buffer;
            }
        }
    
        return 0;
    }
    

    ich brauch da ja einen offset? if(mmhandle->memory_array[i].mem_used_flag == 0)

    cu



  • muss wohl so aussehen:

    uint8_t *AllocateMemoryUnit(struct MemoryManager *mmhandle)
    {
    	uint32_t i = 0;
    
    	for(i = 0; i < mmhandle->num_of_units; i++) {
    		if(mmhandle->memory_array[i * mmhandle->unit_size].mem_used_flag == 0) {
    			mmhandle->memory_array[i * mmhandle->unit_size].mem_used_flag = 1;
    			return mmhandle->memory_array[i * mmhandle->unit_size].buffer;
    		}
    	}
    
    	return 0;
    }
    

    warum bekomme ich jetzt da nen error wenn i == 1004 ist? hm



  • in der funktion 'AllocateMemoryUnit' gehst du ja mit 'nem index durch, d.h. es wird immer 'sizeof(MemoryUnit)' weitergezählt. der zusätzlich angehängte speicher wird dabei aber nicht berücksichtigt. vielleicht liegt's daran?
    🙂



  • das kann sein...
    wie fixe ich das?



  • uint8_t *AllocateMemoryUnit(struct MemoryManager *mmhandle)
    {
    	uint32_t i = 0;
    
    	for(i = 0; i < mmhandle->num_of_units; i++) {
    		if(mmhandle->memory_array[i * mmhandle->unit_size] == 0) {
    			mmhandle->memory_array[i * mmhandle->unit_size] = 1;
    			return &(mmhandle->memory_array[(i * mmhandle->unit_size) + 1]);
    		}
    	}
    
    	return 0;
    }
    

    klappt nicht ganz:/



  • mach doch die struct so:

    typedef struct MemoryUnit
    {
        uint8_t mem_used_flag;
        uint8_t *buffer;
    }MemoryUnit;
    

    und in der 'CreateMemoryManager' für jedes 'MemoryUnit' ein:

    (*mmhandle)->memory_array.buffer = malloc (unit_size);
    

    dann kannst du in 'AllocateMemoryUnit' mit dem index weiterzählen und bekommst immer die nächste 'MemoryUnit', in der auch der pointer auf den buffer steckt.

    btw: 'CreateMemoryManager' bräuchte noch 'ne fehlerbehandlung, weil so ein 'malloc' kann auch schief gehen...
    🙂



  • bei mir ist

    sizeof(struct MemoryUnit) == 8
    

    ...wie soll das dann gehn?

    cu



  • so endlich lauefts:

    typedef struct MemoryUnit
    {
    	uint8_t mem_used_flag;
    	uint8_t buffer[1];
    }MemoryUnit;
    
    typedef struct MemoryManager 
    {
    	uint8_t *memory_array;
    	uint32_t unit_size;
    	uint32_t num_of_units;
    }MemoryManager;
    
    uint8_t *AllocateMemoryUnit(struct MemoryManager *mmhandle)
    {
    	uint32_t i = 0;
    
    	for(i = 0; i < mmhandle->num_of_units; i++) {
    		if(mmhandle->memory_array[i * (mmhandle->unit_size + 1)] == 0) {
    			mmhandle->memory_array[i * (mmhandle->unit_size + 1)] = 1;
    			return &(mmhandle->memory_array[(i * (mmhandle->unit_size + 1)) + 1]);
    		}
    	}
    
    	return 0;
    }
    

    kann man sonst noch was verbessern? vista ich will ja nicht fuer jede memory unit malloc aufrufen... ziel ist es nur 1 malloc zu verwenden!


Anmelden zum Antworten