【问题标题】:Setting a Pointer to a block of stack memory?将指针设置为堆栈内存块?
【发布时间】:2018-01-04 21:08:09
【问题描述】:

我想创建一个指向堆栈内存块的指针。我不想复制内容,只是有一个指向它的指针。我该怎么做?

这是我尝试过的......

char p[3][2] = { 1,2,3,4,5,6 };
printf("\nLIST:%d,%d,%d,%d,%d,%d\n", p[0][0], p[1][0], p[2][0], p[0][1], p[1][1], p[2][1]); //works fine 

char pc[3][2] = { 1,2,3,4,5,6 };
char **p = (char**)pc;//No error here... but shows on next line when accessing through the pointer
printf("\nLIST:%d,%d,%d,%d,%d,%d\n", p[0][0], p[1][0], p[2][0], p[0][1], p[1][1], p[2][1]);  //ERROR:  an Exception thrown here... 

【问题讨论】:

  • a 会降低它,因为它是用户定义的类型。
  • 重新打开 - 这是一个 C 问题,其他建议是 C++ ,无论如何问题是不同的(在这个 OP 上只想要 char (*p)[2] 而在另一个问题上 OP 想要指向指针的指针)跨度>
  • @M.M.的确如此,尽管鉴于 OP 报告了建议的解决方案的错误消息,我怀疑他正在使用 C++ 编译。我不同意这个问题是不一样的但是。该问题明确显示了访问pointer[0][1] 的尝试,而指针对指针将不起作用这里的代码片段或多或少相同。然而,接受的答案是不正确的 - 后面有更多选票的答案是正确的。 stackoverflow.com/questions/10165627/…
  • @Clifford in C 答案是很好的做法,但不是该答案所建议的 infinitely nasty。 (实际上我也不会在 C++ 中称它为无限讨厌)。那个线程上的 OP 说那个答案并没有解决他们的问题。
  • @M.M.它没有解决问题,因为他误解了答案。它是一个指向任意数量的一维数组的指针,每个数组都可以被索引。答案缺少的是使用二维指针通过指针访问数组内容的演示。

标签: c pointers visual-c++ stack visual-c++-2017


【解决方案1】:

你必须区分指针和数组。

char **p 表示p 是指向char 的指针。请改用char *p

char *p = &pc;

这不会使您能够使用 p[x][y] 表示法。为此,我们可以这样做:

char (*p)[2] = pc;

当我尝试了您的代码时,它可以工作。这是完整的主要内容:

int main()
{
    char pc[3][2] = { 1,2,3,4,5,6 };
    char (*p)[2] = pc;
    printf("\nLIST:%d,%d,%d,%d,%d,%d\n", p[0][0], p[1][0], p[2][0], p[0][1], p[1][1], p[2][1]);
}

它编译时没有警告(好吧,我没有引入任何以前不存在的警告)并输出:

$ ./a.out 

LIST:1,3,5,2,4,6

要删除警告,请更改

char pc[3][2] = { 1,2,3,4,5,6 };

char pc[3][2] = { {1,2},{3,4},{5,6} };

感谢 M.M 的改进。

【讨论】:

  • 如果我把它改成 char pc[6] = { 1,2,3,4,5,6 };我收到错误消息:'initializing': cannot convert from 'char()[6]' to 'char'
  • @jdl 立即尝试
  • 严重代码说明项目文件行抑制状态错误 C2440 'initializing': cannot convert from 'char ( * )[3][2]' to 'char ( * )[2]'
  • @jdl 你用的是什么编译器?对我来说完美无缺,而不是使用 -Wall -Wextra 发出警告
  • 编译器VS2017
【解决方案2】:

指针是一个变量,用于存储某物的内存地址。因此,您需要将 pc 的内存地址分配给指向 pc 的指针。您可以通过地址运算符 & 获取某物的内存地址。

指向pc的指针是

CHAR *ppc = &pc[0];

或者简单地说:

CHAR *ppc = pc;

【讨论】:

  • 根据您的回复构建:我收到错误:'initializing': cannot convert from 'char()[3][2]' to 'char'跨度>
  • 对不起。我犯了一个错误。由于 pc 是一个数组,因此您需要稍微不同的语法。
【解决方案3】:

这就是我所做的:(我不想在定义它时指定指针的大小。在重新定义时我会指定大小)

//assigning a pointer to a matrix
char pc[3][2] = { 1,2,3,4,5,6 };
char *pp;//this pointer(as a member) will be carried between classes.      
pp = &pc[0][0];//set pointer to the address of the first element:  via:  Igor Tandetnik

//redefining, validation and display
char p[2][3]; 
memcpy(p, pp, sizeof(char) * 6);
printf("\nLIST:%d,%d,%d,%d,%d,%d\n", p[0][0], p[1][0], p[2][0], p[0][1], p[1][1], p[2][1]);

有趣的是,对于一维数组,您将指针设置为数组名称(地址),而不是第一个元素的地址。

char pc[6] = { 1,2,3,4,5,6 };
char *pp;
pp = pc;//set pointer to the address of the 'pc', not the first element  

【讨论】:

    【解决方案4】:

    指针不是数组,char** 不保留索引它可能指向的任何数组的第二维所需的信息。

    因此,您需要一个指向char[2] 数组的指针而不是char**,因为否则pc 的第二维的大小对于p 是未知的,因此无法确定p[n]

    您可以通过如下声明指向数组的指针来解决这个问题:

    char pc[3][2] = { 1,2,3,4,5,6 }; 
    char (*p)[2] = pc;
    printf("\nLIST:%d,%d,%d,%d,%d,%d\n", p[0][0], 
                                         p[1][0], 
                                         p[2][0], 
                                         p[0][1], 
                                         p[1][1], 
                                         p[2][1] ) ;
    

    为了产生正确的结果,p 指针的维度必须与二维数组pc 数组的第二个维度完全匹配。

    【讨论】:

    • 这个答案没有意义
    • 无论如何
    • 您链接到的页面正在隐藏错误消息,代码包含约束违规(char ** 可能不会隐式转换为char (*)[2])。 OP 代码中的char ** 不起作用,因为char ** 表示“指向char*”的指针,并且首先没有任何char * 对象可以指向。正如您所建议的,它与“尺寸和尺寸信息”无关
    • char* p = &pc[0][0]; 会给你一个指向没有维度信息的内存块的指针。
    • @jdl 您在原始问题中从未提及“稍后在 memcpy 上的工作尺寸”。如果您仍然有问题,请发布一个新问题,询问您的实际问题。 (请勿编辑此问题以提出新问题)
    猜你喜欢
    • 2020-03-09
    • 2019-10-23
    • 2012-09-16
    • 2021-09-01
    • 1970-01-01
    • 2015-05-01
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多