C 宏返回指针,Seg错误

C 宏返回指针,Seg错误,c,arrays,string,macros,C,Arrays,String,Macros,所以我有这个代码,它工作得很好 #include <stdio.h> #define B(X) &X struct abc{ char temp[2]; }; void print(char *string) { printf("%s\n", string); } int main() { struct abc *pAbc = malloc(sizeof(struct abc)); pAbc->temp[0] = 'a'; pA

所以我有这个代码,它工作得很好

#include <stdio.h>
#define B(X) &X
struct abc{
    char temp[2];
};

void print(char *string)
{
    printf("%s\n", string);
}
int main()
{
    struct abc *pAbc = malloc(sizeof(struct abc));
    pAbc->temp[0] = 'a';
    pAbc->temp[1] = '\0';
    print(pAbc->temp);
    free(pAbc);
    return 0;
}
你可以试试

printf("%p %p",pAbc->temp,&pAbc->temp);

要查看它们都计算到相同的地址,在
打印
中,您错误地期望双指针会导致无效的内存访问

您是否在启用警告的情况下编译?你应该得到:

prog.c:3:14: warning: passing argument 1 of 'print' from incompatible pointer type [-Wincompatible-pointer-types]
 #define B(X) &X
              ^~
prog.c:17:11: note: in expansion of macro 'B'
     print(B(pAbc->temp));
           ^
prog.c:8:19: note: expected 'char **' but argument is of type 'char (*)[2]'
 void print(char **string)
            ~~~~~~~^~~~~~
打印函数中不需要双指针,因此只需将其修改回使用一个指针,并更改如下:

#define B(X) &X
为此:

#define B(X) X

编辑:

无需使用宏即可轻松实现所需操作,如下所示:

char* temp= pAbc->temp;
print(&temp);

问题是
&pAbc->temp
的类型是
char(*)[2]
,而不是
char**
。事实上,您应该得到一个关于不兼容指针类型的编译错误(或者至少一个警告)(是否启用了警告?)

如果要获取
字符**
,可以执行以下操作:

char *tmp = pAbc->temp;
然后使用
&tmp
作为
print
的参数


但是,你为什么想要额外的间接层次呢?通常,仅当您希望从被调用函数中修改指针时才需要它,在本例中这是不可能的(这基本上意味着更改数组的地址)。我给出的解决方案会起作用,但在这种情况下,您最终会更改
tmp
,这是值得怀疑的有用性。

您向函数发送了错误的参数。这会导致未定义的行为。在结构中发送数组地址的正确方法是使用临时变量

#include <stdio.h>

struct foo {
  char bar[2];
};

static void print(char **string) { printf("%s\n", *string); }

int main() {
  struct foo a = {.bar = "a"};
  char *p = a.bar;
  print(&p);
}
#包括
结构foo{
字符条[2];
};
静态无效打印(字符**字符串){printf(“%s\n”,*string);}
int main(){
结构foo a={.bar=“a”};
char*p=a.bar;
印刷品(p&p);
}

哦!那么,我该如何创建一个创建双指针的宏呢?我要做的是为我要创建宏的一些编译路径传递一个双指针。编辑了这个问题。@RingØ的可能重复我不确定这是否是重复,你为什么这么说?这可能是重复,因为问题的基本原因是
x
&x
返回相同的地址。阅读提到Q&A的文章可以避免这个错误。如果你不同意,就不要投赞成票。
pAbc->temp
&pAbc->temp
不是一回事,如果它是通过宏完成的,与否是无关的。“你向函数发送了一个错误的参数,这是未定义的行为。”-只是为了澄清一下,一般来说,是向期望
int
UB的函数发送
char
?我想不会。@babon我不想这么说。:)是的,我明白。我只是指出这句话对一般意义上的人意味着什么,仅此而已。
char *tmp = pAbc->temp;
#include <stdio.h>

struct foo {
  char bar[2];
};

static void print(char **string) { printf("%s\n", *string); }

int main() {
  struct foo a = {.bar = "a"};
  char *p = a.bar;
  print(&p);
}