【发布时间】:2014-06-06 12:35:39
【问题描述】:
我编写了一个程序,其中涉及的两行整数会定期交换位置。因此,我所做的是分配两个单独的指向整数的指针,这些指针将对所需的行进行建模。然后我将这两个指针放入一个常量指针数组中,这样可以很容易地进行交换。
我遇到的问题完全是错误的。以此为例:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char* a = malloc(sizeof(char)*5);
char* temp[] = {a};
int i, h, k = 'a';
for(i = 0; i < 5; i++)
a[i] = k++;
for(i = 0; i < 5; i++)
printf("%c ", temp[0][i]);
free(a);
return 0;
}
带输出:a b c d e
IdeOne
我不小心尝试通过二阶取消引用访问静态数组中包含的数组成员:“[][]”
我对这个事件没有多想,因为一切编译和运行都很完美,甚至在输出时给出了预期的结果。当我运行内存分析并发现我收到大量寻址错误和所谓的内存泄漏时,问题就出现了。
所以,为了开始调试过程,我想来这里询问为什么会这样以及它是否是有效的 C 语法。我的印象是:
temp[0]
将取消对char*、a 的引用。然后需要进一步取消引用a 才能访问其成员。此外,我的印象是:
temp[row][col]
翻译成:
*(*(temp + row*col) + col)
在运行时。因此,temp[0][i] 的双重取消引用应该给出与temp 的偏移量,并且根本不访问a。
更有趣的是:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char* a = malloc(sizeof(char)*5);
char* b = malloc(sizeof(char)*5);
char* temp[] = {a, b};
int i, h, k = 'a', j = 'A';
for(i = 0; i < 5; i++){
a[i] = k++;
b[i] = j++;
}
for(i = 0; i < 5; i++){
for(h = 0; h < 5; h++)
printf("%c ", temp[i][h]);
puts("");
}
free(a);
free(b);
return 0;
}
在IdeOne 运行时不编译。但是,此代码确实在 c99 模式下使用 Microsoft Visual Studio Professional 2013 和 gcc 编译。
关于如何正确地做我想做的事情有什么想法或建议吗?也就是说,访问包含在静态数组 temp 中的成员 a 和 b 而不使用非常丑陋的语法,例如:
*(temp[i] + sizeof(char)*h)
【问题讨论】:
-
您的第一个程序完全没问题,并且您关于寻址的推理是正确的(
row*col计算除外)。第二个访问temp的五个索引,而只有两个可用。 -
数组不是“dereferenced”。
-
@alk,数组是指向内存的常量指针,因此在使用时会被取消引用。例如,某些
int* foo[5]数组实际上与指向内存块sizeof(int)*5的常量整数数组相同。因此foo[2]指向第三个整数,但也可以使用*(foo+2)取消对同一成员的引用。也许您是正确的,因为标题中没有使用正确的行话,但每个人似乎都明白了这里的想法。 -
我看不出有任何理由故意使用不正确的措辞。
-
int * foo[5]是一个 指向int的指针数组。我的大小为5 * sizeof (int *)。
标签: c arrays pointers memory malloc