C 中的双星号和"malloc"



我已经研究指针一段时间了,我似乎无法完全理解它。当您从解释指针的教程跳到假设您了解它们的实际函数和代码时,似乎有一个差距没有解释。 让我烦恼的代码如下:

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*)的指针的大小。现在,指向内存开头的指针不应该有一个 * 吗?如果是这样,我们如何将带有 * 的东西分配给 **?我很困惑,如果有人可以提供一些澄清,也许对内存部分有一些见解,那会非常好。

您的代码块是正确的。有了这个声明:

char **output_str = malloc(sizeof(char*));

output_str 是指向 char 指针的 char 指针,或者它可以被视为字符的 2d 数组或字符矩阵。

图形表示:

Memory Address | Stored Memory Address Value
----------------------------------------------
0              |     .....
1              |     .....
2              |     .....
3              |     .....
4              |     .....
5              |     .....
6              |     .....
.              |     .....
.              |     .....
.              |     .....
n-1            |     .....

将内存想象成一个非常大的数组,您可以在其中通过其内存地址访问位置(在本例中,我们将地址简化为自然数。实际上它们是十六进制值)。"n"是内存的总量(或大小)。由于内存计数并从 0 开始,因此大小等效于 n-1。

1. 当您调用:

char **output_str = malloc(sizeof(char*));

操作系统和 C 编译器为我们完成了这项工作,但我们可以认为我们的内存已经更改。 例如,内存地址 3 现在有一个指向名为output_str字符指针的字符指针

Memory Address | Name - Stored Memory Address Value (it points to ...)
-----------------------------------------------------
0              |     .....
1              |     .....
2              |     .....
3              |     output_str = undefined
4              |     .....
5              |     .....
6              |     .....
.              |     .....
.              |     .....
.              |     .....
n-1            |     .....

2. 现在如果我们说:

*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            |     .....

3. 我们声明一个静态实例化的字符:

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" 

这是一个真正的疑问。我会尽力为你说清楚。 从您问题中的详细信息来看,我假设(阅读,"非常确定")您了解malloc内存和相应的返回类型。

你有一个疑问,如果malloc返回一个指针(void*),它怎么能转换为指针到指针(char**)。

  1. char **output_str等效于char *(*output_str)这意味着*output_str是指向某些类型char数据的指针。所以,这就是malloc回归它的内容。
  2. 同样,您会看到malloc返回指针。但本质上,你有一个分配给字符(char*)的指针的内存,"字面上"的意思是,malloc返回一个指针(void*)到你char*的内存,这使得它成为一个指向char的指针,即char**

可以将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"

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("%cn",**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] */

理解malloc的简单解决方案:

malloc(sizeof(Each_Element) *Number_Of_Elements) 返回新缓冲区的地址(又名:指针)。在这个缓冲区中,每个元素都有相同的大小:sizeof(Each_Element),并且有Number_Of_Elements个元素。

例如:

malloc(sizeof(char))返回一个 char 的指针。

malloc(sizeof(char) * 3)返回一个 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 *)将"变形虫指针"(void *)转换为(int *)。

相关内容

  • 没有找到相关文章

最新更新