【问题标题】:Array of a struct with constant parametere in cc中具有常量参数的结构数组
【发布时间】:2014-08-28 02:25:33
【问题描述】:

我定义了以下结构

typedef const struct _txmlAttribute
{
 const char * const ns;
} txmlAttribute;

在下面的函数中,我想初始化我的结构的动态数组:

int func(txmlAttribute* attrs){
    attrs = (txmlAttribute*) { {"as"}, {"bs"}};
    return 0;
}

int main(){
   txmlAttribute* attrs;
   func(attrs);
   return 0; 
}

但我收到以下警告:

main.c: In function ‘func’:
main.c:13:5: warning: braces around scalar initializer [enabled by default]
     attrs = (txmlAttribute*) { {"as"}, {"bs"}};
 ^
main.c:13:5: warning: (near initialization for ‘(anonymous)’) [enabled by default]
main.c:13:5: warning: initialization from incompatible pointer type [enabled by default]
main.c:13:5: warning: (near initialization for ‘(anonymous)’) [enabled by default]
main.c:13:5: warning: braces around scalar initializer [enabled by default]
main.c:13:5: warning: (near initialization for ‘(anonymous)’) [enabled by default]
main.c:13:5: warning: initialization from incompatible pointer type [enabled by default]
main.c:13:5: warning: (near initialization for ‘(anonymous)’) [enabled by default]
main.c:13:5: warning: excess elements in scalar initializer [enabled by default]
main.c:13:5: warning: (near initialization for ‘(anonymous)’) [enabled by default]

那为什么要这样做?以及如何清除它?

【问题讨论】:

  • 你不是在初始化,你是在赋值。
  • @hacks 这是一个复合文字 :) 编辑:从头开始,它 看起来 像一个复合文字。但我想这是数组初始化的尝试。
  • @Quentin;是的。但是它是如何兼容txmlAttribute 类型的呢?
  • @hacks 这将是 2 个txmlAttributes 数组的初始化程序。我猜。
  • @Quentin;正确的。我没想到:)。 MK's answer 在这里似乎是正确的。

标签: c arrays struct constants


【解决方案1】:

我想你想做这样的事情:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
  char* ns;
} txmlAttribute;

int func(txmlAttribute* attrs){
  attrs[0].ns = malloc(3);
  if (attrs[0].ns == NULL)
    return -1;
  strcpy(attrs[0].ns, "as");
  attrs[1].ns = malloc(3);
  if (attrs[1].ns == NULL)
    return -1;
  strcpy(attrs[1].ns, "bs");
  return 0;
}

int main(){
  txmlAttribute attrs[2];
  func(attrs);
  //do something

  free(attrs[0].ns);
  free(attrs[1].ns);
  return 0; 
}

【讨论】:

  • 我认为不能使用strcpy,因为ns已经定义了const
【解决方案2】:

您的问题是{{"as"}, {"bs"}} 将在堆栈上分配,并且在您离开函数范围后将变为无效*。

我会通过编写一个“构造函数”函数来实现,该函数将字段作为参数,为结构及其成员分配(malloc)所需的空间,初始化它们并返回指向该结构的指针。然后填充数组的代码将类似于:

txmlAttribute attrs[2];
attrs[0] = make_txml_attr("as");
attrs[1] = make_txml_attr("bs");

txmlAttribute * make_txml_attr(const char * val) {
  txmlAttribute * res = malloc(sizeof(txmlAttribute));   
  res->ns = strdup(val);
  return res;
}


void free_txml_attr(const char ** p_attr) {
   free(*p_attr->ns);
   free(*p_attr);
   *p_attr = NULL;
}

(我省略了错误检查)

--

无效 - 因为访问它是未定义的行为

【讨论】:

  • 也是语法错误(正确的语法见BLUEPIXY的帖子)
  • 我用gcc编译了代码,不是编译错误。 @MattMcNabb
  • 那么您的建议是什么?我怎样才能做到正确? @MK。
【解决方案3】:

更改为attrs = (txmlAttribute[]) { {"as"}, {"bs"}}; 有效。
(txmlAttribute[]) { {"as"}, {"bs"}}; 是本地范围值。
当您更改指针参数时,Original 也不会更改。
我的建议如下。

int func(txmlAttribute **attrs){
    static txmlAttribute att[] =  { {"as"}, {"bs"}};

    *attrs = att;
    return 0;
}

【讨论】:

  • 所以这个'静态'变量将保留在内存中,我使用后如何释放这个内存? @BLUEPIXY
  • @rezCash 一个静态内存区域的寿命直到应用程序结束。
猜你喜欢
  • 2011-02-04
  • 2012-11-22
  • 1970-01-01
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-03
相关资源
最近更新 更多