从以指针为参数的函数返回指针

沃夫

我正在读这本书:“ C von A bis Z”

有这个例子。

/* ptr14.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Fehler: Funktion gibt die Adresse
 * einer lokalen Variablen zurück. */
/* [ Error: Function returns the address of a
     a local variable. ] */
// ...

/* Möglichkeit2: Speicher vom Heap verwenden */
/* [ Option2: Use memory from the heap ] */
char *test3(void){
   char *buffer = (char *) malloc(10);
   strcpy(buffer, "testwert");
   return buffer;
}

/* Möglichkeit3: Einen Zeiger als Argument übergeben */
/* [ Option3: Pass a pointer as argument ] */
char *test4(char *ptr){
   char buffer[10];
   ptr = buffer;
   strcpy(buffer, "testwert");
   return ptr;
}
int main(void) {
   char *ptr;

   /* ... */

   ptr = test3();
   printf("test3: %s\n", ptr);
   test4(ptr);
   printf("test4: %s\n", ptr);
   return EXIT_SUCCESS;
}

我了解作者在谈论的问题。

为什么test4解决方案有效?

如果我理解正确,不是吗

  1. char buffer[10];在堆栈上分配
  2. 将第一个元素的地址分配buffer给我ptr(居住在先前的范围内)ptr = buffer;

我的期望:

带有ptron的buffer应该是错误的,因为这个范围应该被破坏/清理。

我的想法出了什么问题?

编辑1

我换test4(ptr);ptr = test4(ptr),它仍然有效?

仍然不知道为什么test4(char* ptr)会起作用...

安蒂·哈帕拉(Antti Haapala)

您的想法没有错-您是绝对正确的。好的工作,您现在比使用本书的人更懂C编程语言。

这本书是一文不值的-第三修订版,它以令人毛骨悚然的例子教了3年前的过时C语言。你正好是幸运test4某些编译器中,放置数组第一个元素的地址只是抑制了警告,并且数组恰好位于堆栈上的正确位置,并且不会被覆盖。但是GCC 8.3并没有被中间变量所欺骗。


在功能上

char *test4(char *ptr){
    char buffer[10];
    ptr = buffer;
    strcpy(buffer, "testwert");
    return ptr;
}

ptr在函数内部使用绝不会影响函数外部的指针。它的工作在原来的例子,因为ptr指向从返回的值test3,这是从堆分配。当您将其替换ptr = test4(ptr);ptr变量时,将获得完全未定义的行为,因为现在指向变量的生存期。当发生未定义的行为时,程序可能会执行任何操作,包括(C11 3.4.3p1):

[...]完全忽略这种情况,结果不可预测[...]

具有“无法预期的结果”,包括其“按预期”工作的可能性。


上一个公告点列出了以下选项之一:

  • [您正在使用]调用该函数时作为参数传递的缓冲区[...]

[您将使用]作为参数传递给函数的缓冲区对于此选项,test4应阅读

// use the **array** starting from *ptr
char *test4(char *ptr){
    // use a **different** string here so that you can verify
    // that it actually *works* (max 9 characters!)
    strcpy(ptr, "testval 4");
    return ptr;
}

甚至也许

void test4(char *ptr){
    strcpy(ptr, "testval 4");
}

文档指出,在调用此函数之前,ptr应指向至少10 chars的数组

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章