【问题标题】:How to tell difference between dynamically allocated char* and static char*如何区分动态分配的 char* 和静态 char*
【发布时间】:2015-05-06 04:18:54
【问题描述】:

在我正在处理的程序中,我有一个类似的结构

typedef struct _mystruct{
    char* my_string;
} mystruct;

大部分时间my_string是使用malloc分配的,所以有一个函数调用

free(mystructa->my_string);  

通常这是可行的,但在某些时候,my_string 被设置为文字

my_string = "This is a literal"; 

在我调用 free() 之前,有没有办法区分这两者?

【问题讨论】:

  • 据我所知没有可靠/便携的方式。
  • 查看第二个答案...stackoverflow.com/questions/9504588/… - “理想情况下,malloc() 调用和 free() 调用应该出现在同一个“设计级别”(在同一个实现文件中)模块),它们应该完美匹配:每个 malloc() 一个 free()"
  • 你不应该从那个角度解决你的问题。更好地使用所有权模式:存储在内存中(通过指针)的每个对象都应该由程序的某些部分拥有。结构字段内的缓冲区通常由该结构拥有,因此 1)您应该始终将动态分配的缓冲区分配给结构字段(绝不是静态字符串)和 2)您应该始终在释放 struct 时释放内存。
  • 这个问题详细解答了对象如何存储在内存中以及为什么这个任务无法解决:stackoverflow.com/questions/16360620/…
  • 我将始终对字符串进行 strdup,以便我拥有要封装的字符串。那么如果调用者传递了一个本地的、常量的、静态的所有工作,即使他们传递了堆字符串然后释放它

标签: c arrays string pointers free


【解决方案1】:

没有办法可靠地区分指向文字的指针和指向已分配内存的指针。您将不得不推出自己的解决方案。有两种方法可以解决这个问题:

1) 在struct 中设置一个标志,指示是否应该释放指针。

typedef struct _mystruct {
    char *my_string;
    int string_was_allocated;
} mystruct;

mystructa.my_string = malloc(count);
mystructa.string_was_allocated = 1;
.
.
if (mystructa.string_was_allocated)
   free(mystructa.my_string);

mystructa.my_string = "This is a literal";
mystructa.string_was_allocated = 0;

2) 始终使用strdup 动态分配。

mystructa.my_string = strdup("This is a literal");
free(mystructa.my_string);

这两种方法都涉及对现有代码的更改,但我认为解决方案 2 更加健壮、可靠和可维护。

【讨论】:

    【解决方案2】:

    动态内存和静态内存去不同的地方:栈和堆

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main(int argc, char* argv[]) {
    
    char aString[] = "this is a string";
    
    printf("the string is located at %x \n", &aString);
    
    
    char * pString = (char*) malloc(sizeof(char) * 64);
    strcpy(pString, "this is a dynamic string");
    
    printf("the pointer is located at %x \n", &pString);
    
    printf("the dynamic string is located at %x \n\n", &*pString);
    
    
    
    return 0;
    }
    
    /************* *** **************/
    
    robert@debian:/tmp$ gcc test.c 
    robert@debian:/tmp$ ./a.out
    the string is located at bfcdbe8f 
    the pointer is located at bfcdbe88 
    the dynamic string is located at 95a3008 
    

    【讨论】:

    • 编译器可以把堆和静态内存放在任何它想要的地方,那么你怎么知道哪个是哪个?
    猜你喜欢
    • 2013-12-18
    • 2013-11-18
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    相关资源
    最近更新 更多