作为C语言的新手,我正在使用指针,特别是双指针。
我的意图是
main
main
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void process1(char **pointer) {
//this should take and change the pointer value from a to x
(*pointer)[0] = 'x';
(*pointer)[1] = '\0';
}
void process2(char **pointer) {
//this should take the pointer, free and NULL it, do a new malloc and set the pointer value to y
char* p = *pointer;
free(p);
p = NULL;
p = malloc(sizeof(char)*2);
p[0] = 'y';
p[1] = '\0';
*pointer = p;
}
void main() {
char* p = malloc(sizeof(char)*2);
p[0] = 'a';
p[1] = '\0';
//should print a
printf("%s\n",p);
process1(&p);
//should print x
printf("%s\n",p);
process2(&p);
//should print y
printf("%s\n",p);
free(p);
p=NULL;
}
//this is the Output as expectd
sh-4.2$ main
a
x
y
我现在的问题是:
process2
指针时,我是否在函数p
中泄漏了内存?我是否需要在某处释放此p
指针?答案 0 :(得分:2)
这个程序表现良好。它可以正确释放所有已分配的内存,并且不会在已分配内存的范围之外写入。
从重新分配先前分配的内存的角度来看,process2
正在做什么是好的。在这种特殊情况下,你要分配与以前相同的内存量,但一般来说,如果这样的函数可能正在扩展已分配的内存,那么传递一个双指针来修改调用函数中的指针变量是有意义的。
对于process1
,通过地址传入的指针没有被修改,只是它所指向的,因此这里不需要双指针。您可以将其定义为:
void process1(char *pointer) {
pointer[0] = 'x';
pointer[1] = '\0';
}
并称之为:
process1(p);
答案 1 :(得分:1)
- 这是一个好习惯吗?
醇>
当你不知道在编译时会收到多少输入数据时,动态内存很有用。您可以轻松地重新分配动态数组的大小,而不能在堆栈上修改数组的大小。
缺点是内存泄漏和可能的分段错误。
您必须free
分配内存。
自动存储上声明的数组更易于使用且速度更快
在您的情况下无需传递指针指针,只需使用
即可void process1(char *pointer) {
pointer[0] = 'x';
process1(p);
在process2中,您可以使用realloc()
,而不是释放和分配新内存。建议pointer
为char*
。
pointer = realloc (pointer, 4 * sizeof(int));
pointer
数组
- 在mallocing p指针时,我是否在函数process2中泄漏了内存?
醇>
不,没有任何内存泄漏或触及范围之外。
如果您正在使用指针,那么使用名为valgrind.
的工具调试程序的良好做法如果您不必使用动态分配,请不要。它容易出错,速度慢,你必须释放数据。
答案 2 :(得分:0)
在函数中释放内存不是一个好主意,除非你100%确定传递的指针已被malloced。否则,如果您忘记它并传递任何其他指针,则极易出错。
您的功能
void process1(char **pointer) { //this should take and change the pointer value from a to x (*pointer)[0] = 'x'; (*pointer)[1] = '\0'; }
不需要char **参数
void process1(char *pointer) {
//this should take and change the pointer value from a to x
pointer[0] = 'x'; // or *pointer = 'x'; or *pointer++ = 'x';
pointer[1] = '\0'; // or *(pointer + 1) = '\0'; or *pointer = '\0';
}