C 语言内存分配问题

GAOHUACSDN 2014-10-11 05:21:18
刚刚在做《剑指Offer》一书中的一道题目,大意是,把一字符数组中的空格替换为字符串 “%20”。我写的程序在有些情况下能够运行成功,但在有些情况下出现 memory clobbered before allocated block 错误,代码如下:(会出错的情况)

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

void replaceSpace(char string[]);

int main()
{
char string[] = "I "; //当输入这种字符串是会出错,但当输入如“hello world”时并不报错,
replaceSpace(string);

printf("%s",string);
//free(string);
return 0;
}

void replaceSpace(char string[])
{
int index, spaceNum;
size_t OriginLen, FinalLen;
int OriginIndex, FinalIndex;

index = 0;
spaceNum = 0;
OriginLen = 0;

while(string[index] != '\0')
{
if(string[index] == ' ')
spaceNum++;
OriginLen++;
index++;
}

FinalLen = OriginLen + spaceNum * 2;
realloc(string,FinalLen);

OriginIndex = OriginLen;
FinalIndex = FinalLen;

while(OriginIndex >= 0)
{
if(string[OriginIndex] != ' ')
{
string[FinalIndex] = string[OriginIndex];
}
else
{
string[FinalIndex] = '0';
string[--FinalIndex] = '2';
string[--FinalIndex] = '%';
}

--FinalIndex;
--OriginIndex;
}
}


各位大大们怎么看?
...全文
159 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
GAOHUACSDN 2014-10-12
  • 打赏
  • 举报
回复
引用 2 楼 xpdavis 的回复:
嗯,此外realloc(string,FinalLen);也不是这么用的,应该是: string = (char *)realloc(string,FinalLen);
恩恩,谢谢!
GAOHUACSDN 2014-10-12
  • 打赏
  • 举报
回复
引用 1 楼 Idle_ 的回复:
你的代码中只要加个判断就会知道realloc必然失败(返回null)。 失败原因很简单: string变量指向的是栈上的空间,realloc分配的是堆上的内存,对堆管理器来说string指向的原始空间在堆上根本不存在。 因此调用后string还是原来那块空间,还是原来那些大小的合法空间,很明显你后面的操作会溢出,如果替换的空格少的话问题还不大,最多就是将传入参数给破坏了(加上debug版本下为防止溢出而在栈上多分配的那些空间),但是如果原始串中多些空格那么你的溢出操作必然破坏函数的返回地址 -- 结果就是return时找不到回家的路了,会跳到一个非法地址上引起程序崩溃。
恩恩,懂了,谢谢咯!
li4c 2014-10-11
  • 打赏
  • 举报
回复
你的代码我没看懂
/*************************************************************************
    > File Name: replac.c
    > Author: Jukay
    > Mail: iloveyouljxcc@163.com 
    > Created Time: 2014年10月11日 星期六 19时36分06秒
 ************************************************************************/
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char * replace(char str[]);
int main()
{
	char string[] = "Hello csdn, I am new here! Take care after!";
	char *res;
	res = replace(string);
	printf("%s\n",res);
	free(res);
	res =NULL;
	return 0;
}

char *replace(char str[])
{
	int space_num=0;
	int i=0;
	int size;
	char *p;
	for(;i <strlen(str); i++)
	{
		if(str[i] == ' ')
			space_num++;
	}
	size = strlen(str) + 2*space_num + 1;
	printf("%d\n",size);
	p = (char *)malloc(size);
	int j;
	for(i =0,j =0;i < strlen(str);)
	{
		if(str[i] == ' ')
		{
			p[j] ='%'; j++;
			p[j] ='2'; j++;
			p[j] ='0'; j++;
			i++;
		}
		p[j] = str[i];
		j++;
		i++;
	}
	p[size] = '\0';
	return p;
}
铖邑 2014-10-11
  • 打赏
  • 举报
回复
嗯,此外realloc(string,FinalLen);也不是这么用的,应该是: string = (char *)realloc(string,FinalLen);
阿呆_ 2014-10-11
  • 打赏
  • 举报
回复
你的代码中只要加个判断就会知道realloc必然失败(返回null)。 失败原因很简单: string变量指向的是栈上的空间,realloc分配的是堆上的内存,对堆管理器来说string指向的原始空间在堆上根本不存在。 因此调用后string还是原来那块空间,还是原来那些大小的合法空间,很明显你后面的操作会溢出,如果替换的空格少的话问题还不大,最多就是将传入参数给破坏了(加上debug版本下为防止溢出而在栈上多分配的那些空间),但是如果原始串中多些空格那么你的溢出操作必然破坏函数的返回地址 -- 结果就是return时找不到回家的路了,会跳到一个非法地址上引起程序崩溃。

69,373

社区成员

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

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