昨日曹兄问我一个问题,想出了一个动态分配二维数组的ANSI C程序。
其实思想很简单,我一开始就想到了,肯定是先建立指针数组,然后每个指针数组再分配连续的空间。
画了个草图,可能看起来不怎么好看。。。
先定义一个指向指针的指针P,char **p,然后动态分配指针数组 *p[row],就是二维数组的行,最后给每个指针数组又动态分配空间p[i][col],其实就是二维数组的列。这样就完成了动态数组的分配。
伪代码:
ParrayRow =动态分配行数组指针,即动态分配指针数组。
for(i = 0; i < row; i++)
begin
ParrayCol = (char *)calloc(col, sizeof(char));
ParrayRow[i] = ParrayCol;
End
返回一个指向指针的指针。
注意问题:我测试的时候,我直接定义**p以后
这样测试:p[0] = “1111111111”;
然后可以打印出来,以为成功了,但是这样赋值:
P[0][4] = 0;
按道理,应该也可以操作,我printf(“%s”,p[0])应该出来:1111。
但是我这样做以后,段错误,内存出错,后来我才意识到我错了,因为我定义的是一个指向指针的指针,我用来指向一个动态分配的2维数组,如果要测试,应该是把数据拷贝进二维数组,strcpy(p,tab)。我用p[0]=”11111111”,其实就是把指针指向了这个字符串。。。。。已经不是对自己分配的2维数组操作了。。。所以出现错误!
太不小心了,这么简单的东西头晕弄错了。
下面是代码:
#include "dynamic_allocate_array.h"
char **array_new(int row, int col)
{
int i = 0;
char *ParrayCol = NULL;
char **ParrayRow = NULL;
//char **p;
ParrayRow = (char **)calloc(row, sizeof(char *));
// printf("%x\n",sizeof ParrayRow);
// printf("%x\n",sizeof (char *));
// printf("%x\n",ParrayRow);
// p = &ParrayRow;
for(i = 0; i < row; i++)
{
ParrayCol = (char *)calloc(col, sizeof(char));
ParrayRow[i] = ParrayCol;
}
return ParrayRow;
}
void array_free(char **p,int row ,int col)
{
int i=0;
for(i=0;i<row;i++)
{
memset(p[i], 0, col);
free((char*)p[i]);
}
free((char**)p);
}
#ifndef DYNAMIC_ALLOCATE_ARRAY_H_
#define DYNAMIC_ALLOCATE_ARRAY_H_
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <mem.h>
char **array_new(int row, int col);
void array_free(char **p,int row ,int col);
#endif
#include "dynamic_allocate_array.h"
int main(void) {
char **p;
char *a[2];
char tab1[] = "1111111111111";
char tab2[] = "22222222222222222222";
char tab3[2][100] = {{"111111111111111111111111"},{"2222222222222222222222222222"}};
a[0]= tab1;
a[1] = tab2;
p = array_new(2,100);
strcpy(p[0],tab1);
strcpy(p[1],tab2);
//p[0] = "112312312313";
//p[1] = "21231231231231231231231231231313";
printf("%s, strlen = %d\n",p[0], strlen(p[0]));
printf("%s, strlen = %d\n",p[1], strlen(p[1]));
p[1][5] = 0;
array_free(p, 2, 100);
p = array_new(2,100);
strcpy(p[0],tab2);
/
return EXIT_SUCCESS;
}