【请教高手】C语言数组指针如何动态分配内存?

散人的纪念 2013-07-21 01:58:59

我写了一个可以分割任意长度字符串的函数,分割符号可以指定,我这里就用空格测试了。没有做多个空格的处理。
参数说明:
char *str[] //保存分割好的二维字符数组
int *plenStr //保存分割好的二维数组的行数
char *test //要分割的字符串
int lenTest //要分割的字符串的长度
char ge//分割符号

代码:


#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main( void )
{
void division( char *str[], int *plenStr, char *test, int lenTest, char ge );//分割任意长度的字符串

char *test = "This is a C program Hello World";//测试字符串
int lenTest = strlen( test );
const char ge = ' ';//判别符
char *str[15];//指针数组
int lenStr = 0;//二维数组的行数
int *plenStr = &lenStr;
int i = 0;

division( str, plenStr, test, lenTest, ge );

if( NULL == str )
{
printf("失败!\n");
}
else
{
printf("成功!\n");
}

for( i = 0; i < lenStr; i++ )
{

printf("str[%d] = %s\n",i,*( str + i ));

}

printf("\n\nMy Hello World!\n");
return 0;
}

//分割任意长度的字符串
void division( char *str[], int *plenStr, char *test, int lenTest, char ge )
{
int i;
int j;
int k;
int n;
int numGe = 0;//判别符数量
int *GeArray = NULL;//判别符位置数组
char *temp = NULL;
int lenTemp;
char *p = (char*)malloc(sizeof(char) * ( lenTest + 3 ) );

*( p ) = ge;//第一个位置增加判别符号

for( i = 0,j = 1; i < lenTest; i++,j++ )
{
*( p + j ) = *( test + i );
}

*( p + j ) = ge;//最后一个位置增加判别符

*( p + j + 1 ) = '\0';//人为设置字符串结束符

for( i = 0; i < strlen(p); i++ )//遍历判别符
{
if( ge == *( p + i ))
{
numGe++;
}
}

GeArray = (int*)malloc( sizeof(int) * numGe);//保存判别符位置的数组

for( i = 0,j = 0; i < ( lenTest + 3 ); i++ )
{
if( ge == *( p + i ) )
{
*( GeArray + j ) = i;
j++;
}
}

for( i = 0, n = 0; i < numGe - 1; i++, n++ )
{
lenTemp = *( GeArray + i + 1 ) - *( GeArray + i );

temp = (char*)malloc(sizeof(char) * lenTemp );//分配每一个字符串的空间
j = 0;
for( k = *( GeArray + i ) + 1; k < *( GeArray + i + 1 ); k++ )
{
*( temp + j ) = *( p + k );
j++;
}
*( temp + j ) = '\0';
*( str + n ) = temp;
}

*plenStr = n;//二维字符数组的维数
}



这个代码在VC6.0和CodeBlocks中运行都没有问题,但是我想要的效果是可以分割任意长度的,这也就意味着分割后的单词数也是不确定的。于是问题出现了,我这个代码只能保存15行,就是说一行字符串超过14个空格之后,这个程序就会崩溃,就算做错误处理,也不能达到效果,
请高手指教一下,怎样才可以让分割后的二维数组的行数没有限制?
...全文
590 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
www_adintr_com 2013-07-22
  • 打赏
  • 举报
回复
在函数里面分配内存, 让外面来释放是一件非常难受的事情. 如果要求传入的源字符串可以修改, 就可以不在函数里面分配内存了, 会方便很多的. 分割函数只需要把分割符替换成 '\0', 然后记录下位置就可以了.
一根烂笔头 2013-07-21
  • 打赏
  • 举报
回复
闲着没事,我也写了一个 没有使用relloc,使用的链表,没有采用拷贝,记载分割符位置!多个连续分割符跳过即可! 供lz参考

#include <stdio.h>
#include <string.h>
struct pos{
	char *p;
	struct pos *next;
};

int segmentation(char *input, struct pos **head, char decollator)
{
	if(!input)
		return 0;

	struct pos *p;
	*head = (struct pos *)malloc(sizeof(struct pos));
	(*head)->p = input;
	(*head)->next = NULL;
	p = *head;
	int i, sum = 0;
	for(i = 0; i < strlen(input); ++i)
	{
		if(*(input + i) == decollator)
		{
			while(*(input + i) == decollator) //去重
				++i;
			struct pos *new = (struct pos*)malloc(sizeof(struct pos));
			new->p = input + i;
			new->next = p->next;
			p->next = new;
			p = new;
			++sum;
		}
	}
	return sum;
}

void output_n(struct pos *head, int num, char decollator)
{
	if(!head || num <= 0)
		return;
	int i = 0;
	struct pos *start = head;
	while(start->next)
	{
		++i;
		if(i == num)
		{
			for(i = 0; (start->p + i) < start->next->p ; ++i)
			{
				if(*(start->p + i) == decollator)
					break;
				printf("%c", *(start->p + i));
			}
			printf("\n");
			break;
		}
		start = start->next;
	}
	if(i == 0)
	{
		printf("%s\n", start->p);
	}
}
int main()
{
	char input[256] = {0};
	printf("string:\n");
	gets(input);

	printf("decollator:\n");
	char decollator;//分割符
	scanf("%c", &decollator);
	struct pos *head, *start, *q;
	int i;
	if(segmentation(input, &head, decollator))
	{
		start = head;
//逐个输出
		while(start->next)
		{
			for(i = 0; (start->p + i) < start->next->p ; ++i)
			{
				if(*(start->p + i) == decollator)
					break;
				printf("%c", *(start->p + i));
			}
			printf("\n");
			start = start->next;
		}
		printf("%s", start->p);

	        //指定输出
		output_n(head, 1, decollator);
//释放结点
		while(head)
		{
			q = head;
			head = head->next;
			free(q);
		}
	}
	
	return 0;
}
AnYidan 2013-07-21
  • 打赏
  • 举报
回复
引用 5 楼 my_live_123 的回复:
二维数组要这样动态分配

char **p = (char**)malloc(Len * sizeof(char *));
for(i = 0; i < Len; ++i)
    p[i] = (char *) malloc(str_len * sizeof(char));
对应的释放

for(i = 0; i < Len; ++i)
    free(p[i]);
free(p);
也可以动态分配足够大的一维数组
一根烂笔头 2013-07-21
  • 打赏
  • 举报
回复
二维数组要这样动态分配

char **p = (char**)malloc(Len * sizeof(char *));
for(i = 0; i < Len; ++i)
    p[i] = (char *) malloc(str_len * sizeof(char));
对应的释放

for(i = 0; i < Len; ++i)
    free(p[i]);
free(p);
水平不流 2013-07-21
  • 打赏
  • 举报
回复
malloc,realloc 用这两个加一些判断语句,应该是可以实现的.
fthislife 2013-07-21
  • 打赏
  • 举报
回复
动态创建多维数组可参考 http://hi.baidu.com/thislife/item/123e05eb163e923386d9debe
fthislife 2013-07-21
  • 打赏
  • 举报
回复
任意分割的,instr表示要分割的字符串,len表示instr字符串长度,ge表示分割符,array表示输入输出参数,传出分割后的数组,返回分割后的数组个数

int func(char **array[],char instr[],int len,char ge)
{
	int i,count = 0,k=0,l;
	for(i = 0;i < len;i++)
	{
		if(instr[i] == ge)
		{
			instr[i] = '\0';
			if(i < len - 1 && instr[i+1] != ge)
				count ++;
		}
	}
	if(instr[0] == '\0')count--;
	*array = (char**)malloc((count+1) * sizeof(char*));
	for(i = 0;i < len;i++)
	{
		if(instr[i] != '\0' && (i == 0 || instr[i-1] == '\0'))
		{
			l = strlen(instr+i);
			(*array)[k] = (char*)malloc((l + 1)*sizeof(char));
			strcpy((*array)[k],instr + i);
			k++;
			if(k == count+1)
				break;
		}
	}
	return count + 1;
}
调用 示例

	char a[] = " aaa ddd fff   ddd  ssss    fffff  dfg d dfg sdf sdf asdf asdf sadf asdf dfg d d fgdf ";
	char **p = NULL;
	int count = func(&p,a,strlen(a),' ');
shucheng36 2013-07-21
  • 打赏
  • 举报
回复
可以参考strtok或strsep函数的实现

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧