字符数组给string赋值报stack overflow是什么问题?

lght 2011-12-05 03:36:32

var
i, iSize: Integer;
SourceId: Cardinal;
szValue1: PChar;//array[0..MAX_PATH - 1] of Char;
szValue2: PChar;//array[0..MAX_PATH - 1] of Char;
sValue1, sValue2: string;
begin
iSize := MAX_PATH * SizeOf(Char);
szValue1 := GetMemory(MAX_PATH * SizeOf(Char));
szValue2 := GetMemory(MAX_PATH * SizeOf(Char));
try
for i := 0 to AList.Count - 1 do
begin
ZeroMemory(szValue1, iSize);
if SetupGetSourceFileLocation(AInf, nil, PChar(AList.Strings[i]),
SourceId, szValue1, MAX_PATH, nil) then
begin
// sValue1 := szValue1;
SetLength(sValue1, lstrlen(szValue1));
CopyMemory(@sValue1[1], szValue1, lstrlen(szValue1) * SizeOf(Char));
ZeroMemory(szValue2, iSize);
if SetupGetSourceInfo(AInf, SourceId, SRCINFO_PATH, szValue2,
MAX_PATH, nil) then
begin
// sValue2 := szValue2;
//第二次循环时,此处报错,不管是直接赋值还是用CopyMemory,字符szValue为Char数组和PChar都试过。
SetLength(sValue2, lstrlen(szValue2));
CopyMemory(@sValue2[1], szValue2, lstrlen(szValue2) * SizeOf(Char));
end
else
szValue2 := '';
OutputDebugString(PChar(sValue2 + '\' + sValue1));
end;
end;
finally
FreeMemory(szValue1);
FreeMemory(szValue2);
end;
end;


SetupGetSourceFileLocation和SetupGetSourceInfo可查看msdn
...全文
375 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
lght 2011-12-16
  • 打赏
  • 举报
回复
有时候还是出现stack overflow的问题,太奇怪了。
金卯刀 2011-12-07
  • 打赏
  • 举报
回复
调用RaiseLastWin32Error,看看提示什么讯息。
lght 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 funxu 的回复:]

Move(szValue1^,szValue2^,len);
[/Quote]
没用。


[Quote=引用 8 楼 avan_lau 的回复:]

看看szValue2是什么,对不对?
另外SetupGetSourceInfo其中的buffersize参数,大小应该是你前面计算的iSize。
[/Quote]

szValue2的值是对的,我只用outputdebugstring输出szvalue2的值完全能运行,赋值给svalue2就报错。
金卯刀 2011-12-06
  • 打赏
  • 举报
回复
看看szValue2是什么,对不对?
另外SetupGetSourceInfo其中的buffersize参数,大小应该是你前面计算的iSize。
funxu 2011-12-06
  • 打赏
  • 举报
回复
Move(szValue1^,szValue2^,len);
lght 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 avan_lau 的回复:]

内存搞乱了。既然使用了string类型变量sValue1, sValue2;就不需要使用copymemory。而且你这样copymemory也不对。
为什么你把“sValue1 := szValue1”注释掉,而改用那种方式?
[/Quote]

就是因为使用sValue1 := szValue1报错(stack overflow),才用copymemory试试的
金卯刀 2011-12-06
  • 打赏
  • 举报
回复
内存搞乱了。既然使用了string类型变量sValue1, sValue2;就不需要使用copymemory。而且你这样copymemory也不对。
为什么你把“sValue1 := szValue1”注释掉,而改用那种方式?
lght 2011-12-06
  • 打赏
  • 举报
回复
找到问题原因了,调用SetupGetInfFileList之后再调用上面的函数就会出错,不仅是上面的setupapi,其它setupapi中有ReturnBuffer参数的应该都会出问题。
至于为什么会报错,暂时没弄明白。
lght 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 avan_lau 的回复:]

PChar赋值给String类型变量,delphi编译器会自动加代码转的。
从你的测试代码看,多分配两个字节或 加一个0结尾或 调用StrPas 就没问题。说明直接赋值过程的代码有问题。可以的话,调出CPU view窗口,看里面的汇编码执行过程,看看他是怎么转换的。
[/Quote]

调用strpas是有问题的,我说没问题的是我16楼说的那三种方式。

跟踪了汇编代码,跟到getmem.inc里的sysgetmem,只是汇编不太懂
金卯刀 2011-12-06
  • 打赏
  • 举报
回复
PChar赋值给String类型变量,delphi编译器会自动加代码转的。
从你的测试代码看,多分配两个字节或 加一个0结尾或 调用StrPas 就没问题。说明直接赋值过程的代码有问题。可以的话,调出CPU view窗口,看里面的汇编码执行过程,看看他是怎么转换的。
lght 2011-12-06
  • 打赏
  • 举报
回复

sValue := szValue + #0;
if Result.IndexOf(sValue) = -1 then
Result.Add(sValue);



SetLength(sValue, lstrlen(szValue) + 2);
CopyMemory(@sValue[1], szValue, lstrlen(szValue) * SizeOf(Char));
if Result.IndexOf(sValue) = -1 then
Result.Add(sValue);



sValue := StrPas(szValue);
OutputDebugString(PChar(sValue));


这三种都不报错了。
lght 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 avan_lau 的回复:]

看方法内变量、参数声明,不会是变量分配过大问题。除非是Pchar转给string的数据有问题,导致转换异常。
[/Quote]

都改了,应该不是转换的问题,看下面代码注释。


function GetSections(AInf: HINF): TStrings;
var
szValue: PChar;
sValue: string;
i, iSize: Integer;
begin
Result := TStringList.Create;
iSize := MAX_PATH * SizeOf(Char);
szValue := StrAlloc(iSize);
try
ZeroMemory(szValue, iSize);
i := 0;
if SetupEnumInfSections(AInf, i, szValue, iSize, nil) then
repeat
if GetLastError = ERROR_NO_MORE_ITEMS then
Break;
//这里加上#0就不报错了,但其它地方不行(如调用SetupGetStringField之后),见鬼
// sValue := szValue + #0;

sValue := StrPas(szValue);
OutputDebugString(PChar(sValue));

//这里多分配一个Char也好了,又见鬼
// SetLength(sValue, lstrlen(szValue) + SizeOf(Char));
// CopyMemory(@sValue[1], szValue, lstrlen(szValue) * SizeOf(Char));

//下面两句去掉,也不报错了,真见鬼了
if Result.IndexOf(sValue) = -1 then
Result.Add(sValue);

Inc(i);
ZeroMemory(szValue, iSize);
until not SetupEnumInfSections(AInf, i, szValue, iSize, nil);
finally
StrDispose(szValue);
end;
end;
金卯刀 2011-12-06
  • 打赏
  • 举报
回复
看方法内变量、参数声明,不会是变量分配过大问题。除非是Pchar转给string的数据有问题,导致转换异常。
金卯刀 2011-12-06
  • 打赏
  • 举报
回复
很可能是取出来的字符有问题。
前面说的,传给SetupGetSourceInfo的参数bufferSize是否已调过来?用你前面计算的isize。
d2009以上,char是两个字节的。另外一个api参数也要改为isize。
lght 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 avan_lau 的回复:]

可能要先确认是不是字符问题。
试着把默认栈大小调高,看还会不会出错?
另外你的delphi版本是?
[/Quote]

调高也不行

我的delphi2010


[Quote=引用 11 楼 sz_haitao 的回复:]

一般使用strpas和strpcopy
[/Quote]
strpas试过了。
haitao 2011-12-06
  • 打赏
  • 举报
回复
一般使用strpas和strpcopy
金卯刀 2011-12-06
  • 打赏
  • 举报
回复
可能要先确认是不是字符问题。
试着把默认栈大小调高,看还会不会出错?
另外你的delphi版本是?
lght 2011-12-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sgzhou12345 的回复:]

数据传递有问题吧
[/Quote]

哪里有问题?帮忙看看,这个代码不长吧
山东蓝鸟贵薪 2011-12-05
  • 打赏
  • 举报
回复
数据传递有问题吧
notebook800 2011-12-05
  • 打赏
  • 举报
回复
lz的意思应该是为什么溢出,不是翻译stack overflow
加载更多回复(1)

1,184

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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