【问题标题】:How to clean up a chunk of memory and put new variables there?如何清理一块内存并将新变量放在那里?
【发布时间】:2021-02-14 12:16:01
【问题描述】:

我打算清理一块内存,然后在其中放入一个结构变量并在新清理的内存中分配新值,但我无法从指针变量指向的地址启动结构变量(ptr=00D51590) .如程序output中红色箭头所示,我无法摆脱旧内存变量的残余。

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

struct DataSet{
    char data1;
    int data2;
    char data3;
    short data4;
};

int main(){

uint8_t *ptr;

    struct DataSet data;

    ptr=calloc(16,sizeof(uint8_t));

data.data1=0x11;
data.data2=0xAABBCCDD;
data.data3=0x55;
data.data4=0xAABB;

printf("Value of ptr=%p\n\n",ptr);
ptr=(uint8_t*)&data;
uint8_t totalSize=sizeof(struct DataSet);

printf("Memory address                  Content\n");
printf("=======================================\n");

for(uint8_t i=0;i<totalSize;i++){
    printf("%p=                         %X\n",ptr,*ptr);
    ptr++;
}
printf("\n\nTotal memory consumed by struct variable=%d\n",sizeof(struct DataSet));
return 0;
}

【问题讨论】:

  • 您正在使用ptr = (uint8_t*) &amp;data; 泄漏内存,因为ptr 指向ptr = calloc(16, sizeof(uint8_t)); 分配的空间
  • 另外,请更好地格式化您的代码。你可以使用这样的在线工具techiedelight.com/tools/clike

标签: c pointers memory


【解决方案1】:

这条指令已经分配了内存(在栈上):

struct DataSet data;

这会在堆上分配内存其他地方

ptr=calloc(16,sizeof(uint8_t));

因此,您尝试做的事情永远不会奏效。

你可以这样做:

struct DataSet *data; // This is now a pointer

data = calloc(1, sizeof(struct Dataset));
ptr  = data; // The two pointers point to the same memory

data->data1 = 0x11;

或者您可以使用旧代码将 ptr 分配给 &data,现在 ptr 指向堆栈。真的不推荐“手动”操作内存。

您可能还想使用valgrind 来检查代码中的潜在问题。

【讨论】:

    【解决方案2】:

    您想要指针双关语(不好,但如果您只访问 sizeof(char) 长数据和动态分配的指针,就可以了)。可能你想要:

    #include <inttypes.h>
    
    struct DataSet{
        char data1;
        int data2;
        char data3;
        short data4;
    };
    
    int main(void){
    
        uint8_t *ptr;
    
        struct DataSet *data;
    
        ptr=calloc(16,sizeof(*ptr));
    
        data = (void *)ptr;
        data -> data1=0x11;
        data -> data2=0xAABBCCDD;
        data -> data3=0x55;
        data -> data4=0xAABB;
    
        printf("Value of ptr=%p %p\n\n",(void *)ptr, (void *)data);
    
        printf("Memory address                  Content\n");
        printf("=======================================\n");
    
        for(uint8_t i=0;i<16;i++){
            printf("%p=                         %"PRIx8"\n",(void *)ptr + i,ptr[i]);
        }
        printf("\n\nTotal memory consumed by struct variable=%d\n",sizeof(*data));
        free(ptr);
        return 0;
    }
    

    https://godbolt.org/z/r73K81

    但一般来说,联合双关语更安全

    struct _DataSet{
        char data1;
        int data2;
        char data3;
        short data4;
    };
    
    union DataSet
    {
        struct _DataSet ds;
        uint8_t raw[sizeof(struct _DataSet)];
    };
    
    int main(void){
    
        union DataSet *data;
    
        data = calloc(sizeof(*data),1);
    
        data -> ds.data1=0x11;
        data -> ds.data2=0xAABBCCDD;
        data -> ds.data3=0x55;
        data -> ds.data4=0xAABB;
    
        printf("Value data=%p %p\n\n", (void *)data);
    
        printf("Memory address                  Content\n");
        printf("=======================================\n");
    
        for(uint8_t i=0;i<16;i++){
            printf("%p=                         %"PRIx8"\n",(void *)&data -> raw[i], data -> raw[i]);
        }
        printf("\n\nTotal memory consumed by struct variable=%d\n",sizeof(*data));
        free(data);
        return 0;
    }
    

    https://godbolt.org/z/dM55Ej

    【讨论】:

      猜你喜欢
      • 2020-07-14
      • 1970-01-01
      • 1970-01-01
      • 2017-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      • 1970-01-01
      相关资源
      最近更新 更多