代码之家  ›  专栏  ›  技术社区  ›  Art Em

为字符串动态分配内存

  •  4
  • Art Em  · 技术社区  · 8 年前
    char* test() {
        char* returnValue = "test";
        return returnValue;
    }  
    char* test=test();
    printf("%s",test);
    

    使用安全吗?它和

    char* test {
        char* returnValue=strdup("test");
        return returnValue;
    }
    char* test=test();
    printf("%s",test);
    

    如果是,那么我以后应该释放它吗?它们似乎都工作正常。

    4 回复  |  直到 8 年前
        1
  •  3
  •   alk    8 年前

    是一样的吗

    不,不是。


    char * test1() {
      char * returnValue = "test";
      return returnValue;
    }  
    

    上述代码将固定地址返回给 常数 字面意义的 "test" . 这将是 相同的 每次调用函数时的地址。

    它是 内存的动态分配。

    正在执行

    printf("%d\n", test1() == test1());
    

    将打印

    1
    

    表示“true”,返回的两个地址相同。

    打开“ 康斯特内斯 "

    更好地反映 test1() 最好定义如下:

    const char * test1() {
      const char * returnValue = "test";
      return returnValue;
    }  
    

    char * test2 {
      char * returnValue = strdup("test");
      return returnValue;
    }
    

    上述代码将地址返回到 新分配的 已复制的内存区域 “测试” 进入这将是一个 不同的 *1 每次调用函数时的地址。

    *1: 至少“不同”,只要之前调用 测试2() 还没有 免费() ed已经

    内存的动态分配。因此,需要调用 free() 传入返回的地址 strdup() (内部调用 malloc() )如果不再需要,则释放内存。

    正在执行

    printf("%d\n", test2() == test2()); /* leaks memory: 2 times 4+1 char */
    

    将打印

    0
    

    表示“false”,返回的两个地址不同。

    为了完整性:为了避免泄漏,请按照上面的代码片段执行

    char * p, * q;
    printf("%d\n", (p = test2()) == (q = test2()));
    free(p);
    free(q);
    

    使用安全吗

    从形式上讲,这两个代码片段的代码都是正确的。

    使用哪一个以及使用是否“安全”完全取决于用例和上下文。

        2
  •  2
  •   H.S.    8 年前
    char* test() {
        char* returnValue = "test";
        return returnValue;
    }  
    

    使用安全吗?

    是的,只要您不想修改 returnValue 这是一个 字符串文字 . 字符串文字具有静态存储持续时间,因此 在程序的整个生命周期内保持活动状态 但试图修改字符串文字的内容是未定义的行为。

    它和

    char* test {
        char* returnValue=strdup("test");
        return returnValue;
    }
    

    答案是-

    strdup()

    Returns a pointer to a null-terminated byte string, which is a duplicate of the string pointed to by str1. The returned pointer must be passed to free to avoid a memory leak.

    这个 strdup() 使用 malloc() 要获取新字符串的内存,新字符串如下 "test" . 它一直保持分配状态,直到它被显式释放或程序结束 . 因此,应该使用 free() 一旦你完成了。此外,您还可以修改 strdup() 但请确保不要访问超出分配的内存块。

        3
  •  1
  •   Andriy Berestovskyy    8 年前

    使用安全吗?

    是的,除非您尝试更改字符串。实际上没有分配,因此每次函数都会返回指向内存中相同位置的完全相同的指针。

    它和

    不,是 strdup() 进行分配并返回新分配的内存。

    如果是,那么我以后应该释放它吗?

    不是,但之后仍需要释放内存 strdup() 过后

    它们似乎都工作正常

    对于 printf() 这很好,除非你试图改变那些字符串。。。您将无法更改 char* returnValue = "test" 字符串,但您可以在 strdup()

        4
  •  0
  •   emi jwcoder    8 年前

    在这两种情况下, "test" 在中分配 堆栈 作为内存的只读部分( const char ).

    在第一个块中,返回指向 “测试” . 如前所述,在对函数的调用中,这将始终是相同的值。由于其只读属性,尝试释放或修改它将引发执行错误( munmap_chunk(): invalid pointer 当试图释放时, 分段故障 尝试修改时)。

    在第二个块中,返回指向 . 您有责任使用 free() 或同等产品。您可以自由修改此变量,甚至可以重新分配这部分内存。

    您可以随时进行自己的测试:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char* test1() {
        char* returnValue = "test";
        return returnValue;
    }  
    char* test2() {
        char* returnValue = strdup("test");
        return returnValue;
    }
    
    int main(void)
    {
       char* vtest1 = test1();
       printf("%s => %p\n", vtest1, &vtest1);
       char* vtest2 = test2();
       printf("%s => %p\n", vtest2, &vtest2);
    
       printf("Freeing 2nd test...\n");
       free(vtest2);
    
       printf("Trying to modify 1st test...\n");
       vtest1[0] = 'p';
       printf("Freeing 1st test...\n");
       free(vtest1);
    
       return 0;
    }
    
    推荐文章