【问题标题】:pointer to struct member指向结构成员的指针
【发布时间】:2012-03-01 17:41:47
【问题描述】:
typedef struct
{   
    int A;
    int B;

    char* C; // problem is here
}foo;

int SetA(void)
{
    ....
    return retval;
}

int SetB(void)
{
    ....
    return retval;
}

const char* bar(void)
{
    .....
    char* retval="return val";
    .....
    return retval;
}

void SetFoo(foo* paramFoo)
{
paramFoo->A = SetA();
paramFoo->B = SetB();

paramFoo->C = bar();

}


static foo staticFoo;

void main()
{   
    SetFoo(&staticFoo);
    printf("%s",staticFoo.C);// printing
}

一切都会好起来的,但 struct foo 中的“char*C”写得不好。为什么?我需要知道我是否犯了错误以及如何纠正它?我已经运行了 bar(),它返回了正确的值。

谢谢 ~ 最大

【问题讨论】:

  • “不会写好”是什么意思。你怎么知道?
  • @cnicutar 什么都不会写,当我尝试打印它时,它什么也没给我。
  • @cnicutar printf("%s",staticFoo.C);// 打印

标签: c linux pointers gcc struct


【解决方案1】:

我更喜欢使用malloc 和后来的free 它,这样我就不必担心只读字符串文字何时被破坏。

 const char* bar(void) 
 {     
     const char* retval="return val";
     char * value = malloc( strlen(retval) + 1 ); // +1 for the termination 
                                                  // character
     strcpy( value, retval );
     retrun value ;
 }

当不再需要返回值时,记住free

【讨论】:

  • 我很好奇——这实际上是如何解决问题的?问题是指针分配吗?
  • @DrewDormann 我认为只读字符串(bar 中的 retval)在我可以在 SetFoo() 中使用它之前就被破坏了,所以动态内存分配 (malloc) 是不错的选择,因为我可以破坏它(免费)只要我想。
  • @MaxwellS:我认为其他地方的代码错误地覆盖了该内存,而此更改只是隐藏了该错误。在 C 中,只读字符串在离开作用域时不会“被破坏”……它必须存在于内存中的某个地方,函数才能再次工作。佩里的回答很好地描述了这一点。
【解决方案2】:

正如你所说的那样,这个例子似乎有问题,因为它应该确实有效。

给出的其他几个答案似乎不准确地集中在 bar 返回局部变量的想法上,但事实并非如此——它返回的字符串是在编译时分配的,而不是在堆栈上动态分配的。实际上,指向所述字符串的指针在技术上可以安全地返回到后面的代码。

我的猜测是您的示例不能准确反映您的实际测试代码。

【讨论】:

    【解决方案3】:

    函数栏中的字符串是一个局部变量。您需要通过 malloc 内存缓冲区来创建它或将其声明为全局变量。

     char* bar(void) 
     {     
         char* retval=malloc(100*sizeof(char)); //malloc the buffer
         strcpy( retval,"return val");
         retrun retval ;
     }
    

    char * str = "return val";
    const char* bar(void)
    {
        .....
        char* retval = str;
        .....
        return retval;
    }
    

    【讨论】:

      【解决方案4】:

      我同意佩里的回答。常量字符串分配在只读数据段中,而不是在堆栈上。在 foo() 中,您返回一个常量字符串,可以从任何地方安全地访问它。

      首先,您手动输入了代码。你没有编译它。在你的主要你有这样的代码:

         SetFoo(&staticfoo);
         printf("%s",staticFoo.C);
      

      您看到对象 staticfoo 和 staticFoo 都不相同。如果你修复它并运行程序,你应该得到打印的字符串。它印在我的情况下。

      【讨论】:

        猜你喜欢
        • 2023-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-24
        • 1970-01-01
        • 2018-05-10
        • 1970-01-01
        相关资源
        最近更新 更多