分配给变量时指针的地址发生变化

时间:2019-02-22 21:52:07

标签: c memory memory-management

我正在为学校项目创建替换内存管理器,但无法将main.c文件中的变量的内存地址与我的mem.c文件中的Node->起始地址进行比较。内存地址的最后8位似乎是相同的,但“节点”->“起始地址”通常在内存地址之前附加一个4位数字。

TLDR我需要测试节点-> x的起始地址==的内存地址,并且它不起作用

printf(“ var x:%p \ n”,x); out = 0x3ee30671
printf(“新节点起始地址:%p \ n”,new_node-> start_address); out = 0x56223ee30671

main.c

#include <stdio.h>

#define USE_REPLACEMENT_MANAGER 1

#if USE_REPLACEMENT_MANAGER


    #undef malloc 
    #define malloc myMalloc

    #undef free
    #define free myFree

    #include "replacement.h"

#else 

    #include <stdlib.h>
    void* (*f) (size_t s) = malloc;

#endif 

int main( int argc, const char * argv[] ){
    char * x = (char *) malloc(16);
    printf ("var x: %p \n", x );
    free(x);
}

replacement.c

#include <stdio.h>
#include "mem.h"
#include "replacement.h"

void* myMalloc( size_t size){
    return getAddress ( size);
}

void myFree( void * ptr ){
    printf("free address: %p \n", ptr);
    mmFree( ptr );
}

replacement.h

#ifdef REPLACEMENT_MANAGER_INCLUDED
#define REPLACEMENT_MANAGER_INCLUDED

void* myMalloc( size_t size);
void myFree( void * ptr );
void printMyMap ( void );

#endif 

mem.c

#include <stdio.h>
#include <stdlib.h>
#include "mem.h"

typedef struct Node{
    int             type;
    size_t          size;
    char*           start_address;
    struct Node*    next;
    struct Node*    prev;
}Node; 

/*
    * PRIVATE FUNCTIONS
*/
void init_heap( void );

/*
    * PRIVATE FILE LEVEL GLOBAL VARIABLES
*/
#define HEAP_SIZE   1000
char * heap = NULL;
Node* head = NULL;


// FUNCTION THAT ALLOCATES SPACE ON REPLACEMENT HEAP AND RETURNS A POINTER TO THE START ADDRESS
void* getAddress ( size_t size ){
    if ( heap == NULL ){
        init_heap();
    }
    Node * curr = head;
    while ( curr -> next != NULL ){
        if ( ( curr -> size < size ) && ( curr -> type == 0 ) ){
            return curr -> start_address;
        } else curr = curr -> next;
    }
    Node* new_node = (Node *) malloc( sizeof(Node) );
    new_node -> type = 1;
    new_node -> size = size;
    new_node -> start_address = ( curr -> start_address ) + ( curr -> size ) + 1;
    new_node -> next = NULL;
    new_node -> prev = curr;

    curr -> next = new_node;

    printf("new node start address: %p \n", new_node -> start_address );
    return new_node -> start_address;
}

// FUNCTION THAT INITIALIZES REPLACEMENT HEAP AND THE HEAD OF THE LINKED LIST
void init_heap( void ){
    heap = malloc( HEAP_SIZE );
    printf("heap : %p \n",heap);
    head = (Node*) malloc( sizeof(Node) );
    head -> type = 1;
    head -> size = 0;
    head -> start_address = heap;
    head -> next = NULL;
    head -> prev = NULL;
}   

void mmFree( void * ptr ){
    Node * curr = head; 
    printf( "%p \n", (char*) curr -> start_address );
    while ( curr -> next != NULL ){
        if  (  curr -> start_address == ptr ){
            printf( "I NEED THIS TO PRINT" );
            curr -> type = 0;
            break; 
        } else curr = curr -> next;
    }

    Node * p = curr -> prev;
    Node * n = curr -> next;

    if ( ( p != NULL ) && ( p -> type  == 0 ) ){
        curr -> start_address = p -> start_address; 
        curr -> size = ( curr -> size ) + ( p -> size );
        p -> prev -> next = curr;
        curr -> prev = p -> prev;
        free ( p );
    }

    if ( ( n != NULL ) && (n -> type == 0) ){
        curr -> size  = ( curr -> size ) + ( n -> size );
        if ( n -> next != NULL ){
            n -> next -> prev = curr;
            curr -> next = n -> next; 
        }else curr -> next = NULL;
        free ( n );
    }

}

mem.h

#ifdef MEM_INCLUDED
#define MEM_INCLUDED

void mmFree( void * ptr);

void* getAddress ( size_t size );

void printHeapMap( void );

#endif 

2 个答案:

答案 0 :(得分:0)

始终启用警告并阅读警告。

当我使用“ g ++ -std = c11 -Wall -Wextra * .c -o main”编译代码(在main中添加缺少的分号之后)时,收到很多关于隐式函数声明的警告以及将整数转换为指针的方式,

main.c: In function ‘main’:
main.c:9:20: warning: implicit declaration of function ‘myMalloc’; did you mean ‘malloc’? [-Wimplicit-function-declaration]
     #define malloc myMalloc
                    ^
main.c:24:25: note: in expansion of macro ‘malloc’
     char * x = (char *) malloc(16);
                         ^~~~~~
main.c:24:16: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     char * x = (char *) malloc(16);
                ^

在C89中,当调用一个尚未声明的函数时,C会隐式假定一个函数声明,例如extern int func_name();,但是如果函数定义实际上并未使用与int兼容的返回类型,行为是不确定的。自C99以来,调用未声明的函数的格式是错误的,但是gcc仍然允许使用旧规则和警告来使用它,即使指定了新的标准版本。

所以可能发生的情况是,编译器在某个时候假设您实际返回指针的函数正在返回int值,导致仅使用了某些值位。

因此,通常应通过编写并包含正确的标头来确保每个调用函数的声明都是可见的。

答案 1 :(得分:0)

这里有个问题:

void mmFree( void * ptr ){
    Node * curr = head; 
    printf( "%p \n", (char*) curr -> start_address );
    while ( curr->next != NULL ){
        if  (  curr -> start_address == ptr ){
            printf( "I NEED THIS TO PRINT\n" );
            curr -> type = 0;
            break; 
        } else curr = curr -> next;
    }

考虑释放列表中最后一项的情况。循环将在检查之前终止,因为最后一项的下一个指针将为null。这不是您想要的,因为确实需要对最后一个节点进行操作。

修复很简单,只需将其更改为

void mmFree( void * ptr ){
    Node * curr = head; 
    printf( "%p \n", (char*) curr -> start_address );
    while ( curr != NULL ){
        if  (  curr -> start_address == ptr ){

在处理curr == NULL的情况后,您还需要修正代码,仅当用户错误地尝试释放未由malloc替换分配的指针或已经由malloc替换分配的指针时,才应该修复该代码。释放。