宏返回一个指针,Seg错误

时间:2022-06-01 16:55:31

So I have this code which works fine

这段代码运行得很好。

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

but this does not work

但这行不通

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

as I understand it the macro defination should return the address of the variable.

根据我的理解,宏观定义应该返回变量的地址。

This function works fine with int.

这个函数对int很适用。

EDIT:

编辑:

Sorry I forgot to mention what I wanted to do, I want to pass a pointer to a pointer to the function, since I want to do it only for some compile paths I want to set an option like

抱歉,我忘了说我想做什么了,我想传递一个指向函数指针的指针,因为我想只对我想设置的一些编译路径做这个

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

4 个解决方案

#1


1  

Did you compile with warnings enabled? You should get:

您是否使用已启用的警告进行编译?你应该得到:

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)
            ~~~~~~~^~~~~~

You don't need a double pointer in your print function, so just modify it back to using one pointer, and change this:

打印函数中不需要双指针,因此只需将其修改为使用一个指针,然后更改如下:

#define B(X) &X

to this:

:

#define B(X) X

EDIT:

编辑:

What you want to do can easily be achieved without using a macro, like this:

您想要做的事情可以很容易地实现,而不需要使用这样的宏:

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

#2


1  

You can try

你可以试着

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

to see they both evaluate to same address, inside print you are wrongly expecting double pointer leading to invalid memory access

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

#3


1  

The problem is that &pAbc->temp has type char (*)[2], not char **. In fact, you should have gotten a compilation error (or at least a warning) about incompatible pointer types (do you have warnings enabled?)

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

If you want to get a char **, you can do:

如果你想要得到一个char **,你可以:

char *tmp = pAbc->temp;

then use &tmp as the argument to print.

然后使用&tmp作为参数来打印。

But, why do you want the extra level of indirection? It's generally only needed if you want to modify the pointer from within the called function, which in this case isn't possible (it would basically mean changing the address of the array). The solution I gave will work, but you'd end up changing tmp in that case, which is of questionable usefulness.

但是,为什么你想要额外的间接层呢?通常只需要从调用函数中修改指针,在这种情况下是不可能的(这基本上意味着修改数组的地址)。我给出的解决方案将是有效的,但是在这种情况下,您最终将更改tmp,这是有问题的有用性。

#4


1  

You are sending a wrong argument to your function. That lead to an undefined behavior. The correct way, to sent an address of the address of an array in a structure is to use a temporary variable.

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

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

#1


1  

Did you compile with warnings enabled? You should get:

您是否使用已启用的警告进行编译?你应该得到:

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)
            ~~~~~~~^~~~~~

You don't need a double pointer in your print function, so just modify it back to using one pointer, and change this:

打印函数中不需要双指针,因此只需将其修改为使用一个指针,然后更改如下:

#define B(X) &X

to this:

:

#define B(X) X

EDIT:

编辑:

What you want to do can easily be achieved without using a macro, like this:

您想要做的事情可以很容易地实现,而不需要使用这样的宏:

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

#2


1  

You can try

你可以试着

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

to see they both evaluate to same address, inside print you are wrongly expecting double pointer leading to invalid memory access

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

#3


1  

The problem is that &pAbc->temp has type char (*)[2], not char **. In fact, you should have gotten a compilation error (or at least a warning) about incompatible pointer types (do you have warnings enabled?)

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

If you want to get a char **, you can do:

如果你想要得到一个char **,你可以:

char *tmp = pAbc->temp;

then use &tmp as the argument to print.

然后使用&tmp作为参数来打印。

But, why do you want the extra level of indirection? It's generally only needed if you want to modify the pointer from within the called function, which in this case isn't possible (it would basically mean changing the address of the array). The solution I gave will work, but you'd end up changing tmp in that case, which is of questionable usefulness.

但是,为什么你想要额外的间接层呢?通常只需要从调用函数中修改指针,在这种情况下是不可能的(这基本上意味着修改数组的地址)。我给出的解决方案将是有效的,但是在这种情况下,您最终将更改tmp,这是有问题的有用性。

#4


1  

You are sending a wrong argument to your function. That lead to an undefined behavior. The correct way, to sent an address of the address of an array in a structure is to use a temporary variable.

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

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