我一直在研究指针,我似乎无法完全绕过它。当您从解释指向实际函数的指南和假设您了解它们的代码跳转时,似乎存在一个无法解释的差距。 令我烦恼的代码如下:
char **output_str = malloc(sizeof(char*));
好的,我的理解如下,
**output_str is a character
*output_str is a pointer to a character
output_str is a pointer to a pointer to a character
据我所知,malloc()返回一个指向刚刚分配的内存开头的指针,该指针的大小值等于指向字符(char *)的指针的大小。现在,不应该指向内存开始的指针有一个*?如果是这样,我们怎样才能为*分配*?我很困惑,如果有人能提供一些澄清,并且可能对内存部分有一些了解,那将非常好。
答案 0 :(得分:4)
您的代码块是正确的。有了这个声明:
char **output_str = malloc(sizeof(char*));
output_str是一个指向char指针的char指针,或者它可以看作是char的2d数组,或者是char的矩阵。
Memory Address | Stored Memory Address Value
----------------------------------------------
0 | .....
1 | .....
2 | .....
3 | .....
4 | .....
5 | .....
6 | .....
. | .....
. | .....
. | .....
n-1 | .....
想象一下内存是一个非常大的数组,您可以通过其内存地址访问位置(在这种情况下,我们将地址简化为自然数。实际上它们是十六进制值)。 “n”是存储器的总量(或大小)。由于存储器计数并从0开始,因此大小相当于n-1。
char **output_str = malloc(sizeof(char*));
操作系统和C编译器为我们做了,但我们可以认为我们的内存已被更改。例如。内存地址3现在有一个 char指针指向一个名为output_str
的char指针。
Memory Address | Name - Stored Memory Address Value (it points to ...)
-----------------------------------------------------
0 | .....
1 | .....
2 | .....
3 | output_str = undefined
4 | .....
5 | .....
6 | .....
. | .....
. | .....
. | .....
n-1 | .....
*output_str = malloc(sizeof(char));
内存再次被更改。例如。内存地址0现在有一个名为*output_str
的字符指针。
Memory Address | Name - Stored Memory Address Value (it points to ...)
-----------------------------------------------------
0 | *output_str = undefined
1 | .....
2 | .....
3 | output_str = 0
4 | .....
5 | .....
6 | .....
. | .....
. | .....
. | .....
n-1 | .....
char a = 'a';
所以我们的内存再次发生了变化,它已放置在MemoryAddress [6] ='a':
Memory Address | Name -> Stored Memory Address Value (it points to ...)
------------------------------------------------------
0 | *output_str = undefined
1 | .....
2 | .....
3 | output_str = 0
4 | .....
5 | .....
6 | a = 'a' // 'a'is static memory
. | .....
. | .....
. | .....
n-1 | .....
最后,我们调用
*output_str = &a;
我们现在告诉char指针*output_str
指向/引用先前实例化的char a
。
所以我们的最终记忆将如下所示:
Memory Address | Name - Stored Memory Address Value (it points to ...)
-----------------------------------------------------
0 | *output_str = 6
1 | .....
2 | .....
3 | output_str = 0
4 | .....
5 | .....
6 | a = 'a' // 'a'is static memory
. | .....
n-1 | .....
Now printf("Value: " + a) will output "Value: a" printf("Value: " + *output_str[0]) will also output "Value: a" And printf("Value: " + **output_str) will output "Value: a"
答案 1 :(得分:2)
这是一个真正的怀疑。我会尽力为你说清楚。
根据你问题中的细节,我假设(阅读,“非常确定”)你理解malloc
内存和相应的返回类型。
您怀疑如果malloc
返回指针(void*
),它如何转换为指向指针(char**
)的指针。
char **output_str
相当于char *(*output_str)
,这意味着*output_str
是指向char
类型数据的指针。所以,这就是malloc
返回它的原因。malloc
返回一个指针。但实际上,你有一个指向char(char*
)的指针的已分配内存,“字面意思”意味着,malloc
正在将指针(void*
)返回到你拥有的内存中char*
,它是指向char
指针的指针,即char**
。答案 2 :(得分:0)
malloc()
返回void *
,可以隐式转换为任何其他指针类型。在您的情况下,malloc()
分配的空间可用作char *
值的存储空间。请查看以下示例
char str[10]= {'a'};
//char c = 'c';
char **output_str = malloc(sizeof(char*));
*output_str = str; /* Stored address of a char array of size 10*/
//*output_str = &c; // Stored address of a char, its also correct
printf("%c\n",**output_str); /* Will print the char element, if you are using string address it will print first element,
to print other elements in str use (*output_str)[index] */
答案 3 :(得分:0)
将output_char视为指向字符串数组的指针,每个字符串都是指向字符数组的指针。当你执行malloc(sizeof(char *))时,你只提供长度为1的char指针数组,因此* output_char包含一个未初始化的指针(NULL)。
你应该做的是分配足够的指针,这样你就可以指向一堆字符串。假设您要存储N个字符串,所有字符串都由output_char引用。将其初始化为:
// Allocate an array of N string pointers
char **output_str = malloc(sizeof(char*)*N);
然后,您需要为每个字符串分配存储空间:
// Allocate storage for each of the N strings, assume 80 chars max each
// including the null character required at the end of the string
#define MAX_STRING_SIZE 80
int i;
for(i=0; i<N; i++)
// Allocate storage for each of the strings, but they
// still need to have some chars written to this storage
// for these strings to be anything but null strings ""
output_str[i] = malloc(MAX_STRING_SIZE*sizeof(char));
每个C程序的开头都有一个很好的例子:
int main(int argc, char** argv) { /* your code */ }
每个C程序都以此主要定义开头。它接受两个参数,一个是通过命令行传递到程序中的字符串数(包括程序本身的名称),argv是对字符串参数数组的引用。
例如,使用以下命令行参数调用myprog:
myprog -h "Fred" Jones
在main()传递 argc 和 argv 的结果中:
argc = 4
argv[0] = "myprog"
argv[1] = "-h"
argv[2] = "Fred"
argv[3] = "Jones"
答案 4 :(得分:0)
理解malloc的简单解决方案:
malloc(sizeof( Each_Element )* Number_Of_Elements )返回新缓冲区的地址(又名:指针)。在此缓冲区中,每个元素都具有相同的大小:sizeof( Each_Element ),并且有 Number_Of_Elements 元素。
例如:
malloc(sizeof(char))返回char的指针。
malloc(sizeof(char)* 3)返回char的指针,char是char数组的第一个元素,包含3个字符。
malloc(sizeof(char *)* 6)返回一个char指针的指针,该指针是char指针数组的第一个元素,包含6个char指针。
基本上, malloc(sizeof(WHAT))会返回WHAT指针。所以简单地理解: malloc(Sizeof(WHAT))返回(WHAT *)。 malloc(Sizeof(WHAT *))返回(WHAT **) ......等等。
请注意,实际上malloc返回(void *)指针。稍后可以将(Void *)指针强制转换为任何类型的指针。因此,VisualStudio用户的方式很好: int * pbuff =(int *)malloc(sizeof(int)* 6); 函数malloc之前的(int *)转换&#34; Amoeba指针&#34; (void *)进入(int *)。