c/c++语言开发共享stack&realloc问题C ++

int main() { char myString = NULL; realloc(&myString, 5); strncpy((char *)&myString, "test", 5); } 

似乎工作正常,但我仍然有点困惑堆栈与堆,这是允许的吗? myString是否需要手动释放,还是在超出范围时被释放?


编辑:感谢您的回复,所以我认为这同样是非法的

 //I want the code to change myString to "tests" char myString[5] = "test"; realloc(&myString, strlen(myString)+2); myString[4] = 's'; myString[5] = ''; 

    不,这是完全错误的。 realloc只应用于重新分配malloc分配的内存,你所做的只是意外工作,并最终会崩溃

     char *myString = malloc(x); myString = realloc(myString,y); free(myString) 

    你最好使用new和delete,最好还是使用std :: string。

    您发布的代码存在一些问题:

    [关于realloc的返回值:]成功完成后,大小不等于0,realloc()返回指向(可能已移动)分配空间的指针。 如果size为0,则返回空指针或可成功传递给free()的唯一指针。 如果没有足够的可用内存,realloc()将返回空指针并将errno设置为[ENOMEM]。

    如果ptr是空指针,则realloc()的行为类似于指定大小的malloc()。

    更多C ++方法:

    您将此标记为C ++,并且使用C ++的新运算符更安全。 虽然新运算符不允许重新分配,但它可用于分配和重用现有缓冲区(placement new)。

     char *myString = new char[5]; strncpy(myString, "test", 4); //... delete[] myString; 

    甚至:

     #include  //... std::string str = "test"; 

    前2名报价的来源

    这应该不起作用。 你正在重新分配一开始没有被malloced的东西。 不,当它超出范围时它不会被释放 – 当你使用malloc或realloc时,这完全取决于你。

    更新:您的编辑不会改变任何内容 – 您仍然试图重新分配一开始没有被malloced的东西。 此外,您不能忽略realloc的返回值 – 如果realloc必须将内存移动到其他位置,您将在返回中找到它。 换一种说法:

     char* ptr = malloc(4); ptr = realloc(ptr, 5); 

    在realloc之后,ptr可能指向内存中完全不同的位置,继续使用ptr的原始值可能会让你使用已经释放的内存,而不是你想象的那么大。

    这是危险的! 这会破坏你的筹码。 如果你在一个函数的堆栈上重新分配一些然后返回到main()的东西,你实际上最终会覆盖堆栈帧并返回除main()之外的某个地方。 这是一个潜在的安全漏洞。

    尝试运行以下内容。 如果它在realloc上崩溃,你很幸运。 你可以用memcpy(&myString)之类的东西做严重的伤害。

     int dostuff(); int main() { dostuff(); return 0; } int dostuff() { char myString = NULL; realloc(&myString, 5); strncpy((char *)&myString, "test", 5); return 0; } 

    这是你永远不应该做的。 尝试free()或realloc()堆栈变量可能导致未定义的行为,包括(但不限于)损坏的堆栈(导致不可预测的控制流),损坏的堆服务结构,损坏的用户内存。 如果程序刚刚与AV崩溃,你很幸运。 它可能在某些情况下有效,但你永远不应该尝试这样做。

    经验法则:只返回分配给它的内存管理器的内存。 在这种情况下,不要尝试将堆栈变量返回到运行时堆。

    您的程序在语法上是有效的C ++,但它会产生未定义的行为,因为您将堆栈对象的地址传递给堆分配器。 通常这意味着您的程序在执行时会崩溃。

    堆栈和堆是分配给执行程序的进程的两个不同的内存区域。 当您输入一个函数来保存其参数和局部变量时,堆栈会增长,并且当您从函数返回时它会自动收缩。 另一方面,堆是一个单独的地址区域,可以根据需要获取内存,并且必须在不再需要时显式释放。

    如果将局部变量的地址传递给realloc(),它可能会尝试释放其内存并将其分配到其他位置。 由于地址不是来自堆,并且realloc()在堆上运行,因此会失败。 很可能realloc()将检测地址不是来自堆并中止程序。


    除此之外,示例程序包含一些逻辑错误。

     char myString = NULL; 

    您声明一个变量来保存char,而不是字符串。 C风格的字符串具有char*类型,即指向char的指针。

    此外,char被赋予NULL ,地址为零,通常分配给无效指针。 这是编译因为预处理器用文字0替换NULL 。 实际上,您在char中存储了一个零字节,这也是按照惯例,是C样式字符串的终止符。

     realloc(&myString, 5); 

    如上所述,这是非法的,因为您将堆栈对象的地址传递给堆分配器。 您的第二个代码示例中仍然存在此问题。

    此外,您放弃了返回值。 realloc()返回分配新内存的地址。 它可能与以前的地址不同。 它甚至可能是NULL,这是realloc()告诉你内存不足的方式。

     strncpy((char *)&myString, "test", 5); 

    这是正确的,但演员阵容是多余的。


    这是一个更正确的程序版本:

     #include  #include  int main() { /* allocate space for, say, one character + terminator */ char* myString = (char*) malloc(2); /* some code using myString omitted */ /* get more space */ myString = (char*) realloc(myString, 5); /* write to the string */ strncpy(myString, "test", 5); /* free the memory */ free(myString); return 0; } 

    在C ++中,最好完全避免使用realloc()。 例如,您可以使用以下内容:

     #include  int main() { std::string myString; /* some code using myString */ myString = "test"; return 0; } 

    你不必释放myString因为它在堆栈上(在离开范围时会被“释放”)。

    realloc在这里是非法的,地址必须为NULL或先前调用reallocmalloccalloc返回的地址。

    您声明的每个变量都在堆栈中,甚至是指针:

    int * x;

    变量x在堆栈上! 它是类型pointer并保存一个地址。

    x =(int *)malloc(sizeof(int));

    malloc返回的地址赋给变量x! x的内容是一个内存地址!

    你正在做的事情的问题在于你正在捣乱一些不是变量的东西。 您将myString定义为char,因此尝试更改其地址。 那很糟。

    函数realloc()不应该改变传递给它的任何东西。 它需要一个指向堆上某些内存的指针(如果没有分配任何内容,则指向空指针)并返回指向堆上某些内存的指针。

    因此,您提供空指针或指向malloc()或realloc()或calloc()分配的内容的指针,并存储返回的指针。

    就像是

     char * myString = NULL; myString = realloc(myString, 5); 

    会工作,但你会想要free()myString。

    但是,在C ++中,使用std :: string。

    回应你的第二个代码示例:

    是的,这也是非法的。 myString没有使用malloc(或calloc)分配,因此无法使用realloc重新分配,或者使用free释放。

    此外,realloc不会将指针指针作为其第一个参数。 它需要一个指向已分配内存的指针,并返回另一个(可能是不同的)指针。 写这样的电话代替:

     myString = realloc(myString, strlen(myString)+2); 

      以上就是c/c++开发分享stack&realloc问题C ++相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/541937.html

      (0)
      上一篇 2021年1月5日
      下一篇 2021年1月5日

      精彩推荐