给二维数组指针扩容

参考:https://blog.csdn.net/u012199908/article/details/79185921

参考:https://bbs.csdn.net/topics/391936871?page=1

参考:https://zhidao.baidu.com/question/140600641317526125.html

postgres全部由纯C编写,现在要给一个指针数组赋值,但是因为由数组上限要求,所以就和vector那样,需要动态的给二维数组扩容。如果写了扩容方法,如果对函数中的指针重新分配内存,就会导致函数中的指针和实参变化。如下:

#include <iostream>
#include <cstring>

const int MAX = 2;

typedef struct Node 
{
	char x;
	int y;
	Node(char c, int i) :x(c), y(i) {}
}Node;


static int enlarge_capcity(int capcity)//扩容 确定新的容量大小
{
	//乘以二比INT_MAX小 扩容两倍 否则扩容到INT_MAX 
	return (capcity * 2 > INT_MAX) ? INT_MAX : capcity * 2;
}

static void enlarge(char **outer_array, int outer_length, int *capcity)//重新申请数组扩容
{
	char **temp= (char**)malloc(sizeof(char*)*outer_length);
	for (int i = 0; i < outer_length; i++) 
	{
		temp[i] = (char*)malloc(sizeof(Node));
		memcpy(temp[i], outer_array[i], sizeof(Node));
	}
	*capcity = enlarge_capcity(*capcity);
	std::cout << "函数中数组地址:" << outer_array << std::endl;
	outer_array= (char**)malloc(sizeof(char*)**capcity);
	std::cout << "函数中数组地址:" << outer_array << std::endl;
	for (int i = 0; i < outer_length; i++)
	{
		outer_array[i] = (char*)malloc(sizeof(Node));
		memcpy(outer_array[i], temp[i], sizeof(Node));
	}
	
	for (int i = 0; i < outer_length; i++)
	{
		Node *t = (Node*)((char*)outer_array[i]);
		std::cout << t->x << " " << t->y << std::endl;
		
	}
	for (int i = 0; i < outer_length; i++) 
	{
		free(temp[i]);
		temp[i] = NULL;
	}
	free(temp);
	temp = NULL;
	
}






int main()
{
	char **outer_array = (char**)malloc(sizeof(char*)*MAX);//申请内存空间
	int outer_length = 0;//左孩子元组长度
	int capcity = MAX;//元组集合容量 可以扩容

	for (int i = 0; i < 10; i++) 
	{	
		if (outer_length + 1 > capcity)//当前长度加1大于容量 扩容
		{
			std::cout <<"长度:"<<outer_length<<" 容量:"<<capcity << std::endl;
			std::cout<<"扩容前数组地址:"<<outer_array <<std::endl;
			enlarge(outer_array, outer_length, &capcity);
			std::cout <<"长度:" << outer_length << "扩容容量:" << capcity << std::endl;
			//break;
		}
		Node *temp = new Node(i+'0',i);
		//std::cout << temp->x << " " << temp->y << std::endl;
		outer_array[outer_length] = (char*)malloc(sizeof(Node));
		memcpy(outer_array[outer_length],temp,sizeof(Node));
		outer_length++;
	}

	 
	
	for (int i = 0; i < outer_length; i++)
	{
		Node *t = (Node*)((char*)outer_array[i]);
		//std::cout << t->x << " " << t->y << std::endl;
		free(outer_array[i]);
		outer_array[i] = NULL;
	}
	free(outer_array);
	outer_array = NULL;
    std::cout << "Hello World!\n";
	return 0;
}

 

长度:2 容量:2
扩容前数组地址:0086E568
函数中数组地址:0086E568
函数中数组地址:00864F90//地址出现变化 因为重新malloc
0 0
1 1
长度:2扩容容量:4
长度:4 容量:4
扩容前数组地址:0086E568
函数中数组地址:0086E568
函数中数组地址:00864C88
0 0
1 1
2 2
3 3
长度:4扩容容量:8
长度:8 容量:8
扩容前数组地址:0086E568
函数中数组地址:0086E568
函数中数组地址:00864DC8
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
长度:8扩容容量:16

修改有两种方法,一种使用realloc,还有一种是,为了改变char**,参数中就要写char***,但是这个就比较麻烦。

int **a, i;
a=(int**) malloc(sizeof(int*)*100);
for(i = 0; i < 100; i ++)
    a[i] = (int*)malloc(sizeof(int)*2);
//以上 第一次申请完毕, 为a[100][2]
 
a=(int**) realloc(a, sizeof(int*)*150);//扩大到150
//由于realloc可以保证前面部分值不变,所以 前100个不动。
for(i = 100; i < 150; i ++)
    a[i] = (int*)malloc(sizeof(int)*2);

利用上面两个方法,扩容程序编写成功

static void enlarge(char ***outer_array, int outer_length, int *capcity)//重新申请数组扩容
{	
	*capcity = enlarge_capcity(*capcity);
	std::cout << "函数中数组地址:" << *outer_array << std::endl;
	*outer_array= (char**)realloc(*outer_array,sizeof(char*)**capcity);
	std::cout << "函数中数组地址:" << *outer_array << std::endl;
	
	for (int i = 0; i < outer_length; i++)
	{
		Node *t = (Node*)((char*)(*outer_array)[i]);
		std::cout << t->x << " " << t->y << std::endl;
		
	}
	
}

最终代码

// 字符数组拷贝.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <cstring>
#define ARRAY (char **)
const int MAX = 2;

typedef struct Node 
{
	char x;
	int y;
	Node(char c, int i) :x(c), y(i) {}
}Node;


static int enlarge_capcity(int capcity)//扩容 确定新的容量大小
{
	//乘以二比INT_MAX小 扩容两倍 否则扩容到INT_MAX 
	return (capcity * 2 > INT_MAX) ? INT_MAX : capcity * 2;
}

static void enlarge(char ***outer_array, int outer_length, int *capcity)//重新申请数组扩容
{	
	*capcity = enlarge_capcity(*capcity);
	std::cout << "函数中数组地址:" << *outer_array << std::endl;
	*outer_array= (char**)realloc(*outer_array,sizeof(char*)**capcity);
	std::cout << "函数中数组地址:" << *outer_array << std::endl;
	
	for (int i = 0; i < outer_length; i++)
	{
		Node *t = (Node*)((char*)(*outer_array)[i]);
		std::cout << t->x << " " << t->y << std::endl;
		
	}
	
}






int main()
{
	char **outer_array = (char**)malloc(sizeof(char*)*MAX);//申请内存空间
	int outer_length = 0;//左孩子元组长度
	int capcity = MAX;//元组集合容量 可以扩容

	for (int i = 0; i < 10; i++) 
	{	
		if (outer_length + 1 > capcity)//当前长度加1大于容量 扩容
		{
			std::cout <<"长度:"<<outer_length<<" 容量:"<<capcity << std::endl;
			std::cout<<"扩容前数组地址:"<<outer_array <<std::endl;
			enlarge(&outer_array, outer_length, &capcity);
			std::cout <<"长度:" << outer_length << "扩容容量:" << capcity << std::endl;
			//break;
		}
		Node *temp = new Node(i+'0',i);
		//std::cout << temp->x << " " << temp->y << std::endl;
		outer_array[outer_length] = (char*)malloc(sizeof(Node));
		memcpy(outer_array[outer_length],temp,sizeof(Node));
		outer_length++;
	}

	 
	
	for (int i = 0; i < outer_length; i++)
	{
		Node *t = (Node*)((char*)outer_array[i]);
		//std::cout << t->x << " " << t->y << std::endl;
		free(outer_array[i]);
		outer_array[i] = NULL;
	}
	free(outer_array);
	outer_array = NULL;
    std::cout << "Hello World!\n";
	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
长度:2 容量:2
扩容前数组地址:016AE400
函数中数组地址:016AE400
函数中数组地址:016A4F90
0 0
1 1
长度:2扩容容量:4
长度:4 容量:4
扩容前数组地址:016A4F90
函数中数组地址:016A4F90
函数中数组地址:016A4F90
0 0
1 1
2 2
3 3
长度:4扩容容量:8
长度:8 容量:8
扩容前数组地址:016A4F90
函数中数组地址:016A4F90
函数中数组地址:016A5290
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
长度:8扩容容量:16
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
Hello World!

C:\Users\YSA10\source\repos\字符数组拷贝\Debug\字符数组拷贝.exe (进程 18112)已退出,返回代码为: 0。
若要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口...

总结:如果想要对二维指针数组在函数中修改,就需要用三维指针,对指针的修改总要多一个维度,realloc可以保留之前的空间,重新分配,不过貌似地址有变化,那么可能会导致之间分配的内存泄漏,后来看csdn论坛上有人说,不用担心,最后一次释放就ojbk了。

保证释放最后1次realloc()返回的指针就可以了。

realloc()如果成功回返回成功的地址,注意可能和旧地址已经不同了。
如果失败返回NULL,这个时候旧地址依旧可用,请注意旧地址不要被NULL覆盖了。

realloc内存泄漏:https://blog.csdn.net/wangzhang001/article/details/23257397

https://bbs.csdn.net/topics/320234400

最后postgres的修改程序就两行,非常简洁

static void enlarge(char ***outer_array, int outer_length, int *capcity)//重新申请数组扩容
{	
	*capcity = enlarge_capcity(*capcity);
	*outer_array= (char**)realloc(*outer_array,sizeof(char*)**capcity);
}

 


版权声明:本文为BJUT_bluecat原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>