宏返回一个指针,Seg错误

时间:2017-12-01 07:29:04

标签: 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';
    pAbc->temp[1] = '\0';
    print(pAbc->temp);
    free(pAbc);
    return 0;
}

但这不起作用

#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(B(pAbc->temp));
    free(pAbc);
    return 0;
}

据我所知,宏定义应该返回变量的地址。

这个函数适用于int。

编辑:

抱歉,我忘了提到我想做的事情,我想传递一个指向该函数的指针,因为我只想为一些编译路径做这个我想设置一个选项,如

if #defined WIN32
print(B(varible))
elif #defined GCC
print(varible)

4 个答案:

答案 0 :(得分:1)

你可以尝试

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

看到它们都评估到相同的地址,在print内你错误地期望双指针导致无效的内存访问

答案 1 :(得分:1)

编译时是否启用了警告?你应该得到:

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);

答案 2 :(得分:1)

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

如果您想获得char **,可以执行以下操作:

char *tmp = pAbc->temp;

然后使用&tmp作为print的参数。

但是,为什么你想要额外的间接水平?通常只有在你想要从被调用函数中修改指针时才需要它,在这种情况下是不可能的(它基本上意味着改变数组的地址)。我给出的解决方案会起作用,但在这种情况下你最终会改变tmp,这是有用的。

答案 3 :(得分:1)

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

#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);
}