指定给变量时指针的地址会发生变化

问题描述 投票:2回答:2

我正在为学校项目创建替换内存管理器,我在将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 

Memks

#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 );
    }

}

Memkh

#ifdef MEM_INCLUDED
#define MEM_INCLUDED

void mmFree( void * ptr);

void* getAddress ( size_t size );

void printHeapMap( void );

#endif 
c memory memory-management
2个回答
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值,导致只使用一些值位。

因此,请确保所有调用函数的声明都是可见的,通常是通过编写并包含正确的标题。


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替换分配的指针或已经释放的指针时才可能。

© www.soinside.com 2019 - 2024. All rights reserved.