Cstring - 调试断言失败;缓冲太小了

时间:2013-10-08 02:53:03

标签: c++ visual-c++ visual-studio-2008 mfc

我有这段代码在调试期间不断抛出“缓冲区太小”的错误。

        geoGraph.size=limit;
        CString xAxis ="X axis: ",yAxis="Y axis: ";

        for (int x = 0; x < limit; x++)
        {

            xAxis.Format(_T("%s%i  "),xAxis,(x+1));
            yAxis.Format(_T("%s%s  "),yAxis,dialog_test.str[x]);

        }

        xAxis.Format(_T("%s \n%s  "),xAxis,yAxis);// <---Error thrown

        d.SetWindowTextA(xAxis);

我得出结论,错误是由于Cstring xAxis太小而无法包含新文本,我是否正确,如果是,我该如何解决?


感谢。

编辑:我很好奇为什么这个错误只在调试期间显示,而不是在我使用'start without debugging'运行应用程序时(我使用的是VS2008)。

4 个答案:

答案 0 :(得分:8)

没有!真正的问题是:

  1. xAxis格式启动,看到需要更多空间。基于给格式化的所有参数的计算。
  2. 现在重新分配xAxis存储空间。旧指针变为无效,并在调试版本中释放并覆盖它。所以不再有0终止符。内存中填充了可用内存的标准值。
  3. 格式从旧指针(其指向刚刚更改的内容)开始并收集并复制垃圾并找不到0终止符。
  4. 永远不要在格式中使用CString作为目标AND源! 这可能在Release Version中有效,因为Memory MIGHT不会被更改,但是如果它被更改,则行为是未定义的。但这是一个真正糟糕的编码错误。

答案 1 :(得分:2)

CStringT::Format的文档包含以下注释:

  

如果字符串对象本身作为Format的参数提供,则调用将失败。例如,以下代码将导致不可预测的结果:

CAtlString str = _T("Some Data");
str.Format(_T("%s%d"), str, 123);
// Attention: str is also used in the parameter list.

要解决此问题,您可以为参数创建副本,或者 - 在此特定情况下 - 调用CStringT::AppendFormat类成员:

geoGraph.size = limit;
CStringW xAxis = L"X axis: ",
         yAxis = L"Y axis: ";

for ( int x = 0; x < limit; ++x ) {
    xAxis.AppendFormat( L"%i  ", x + 1 );
    yAxis.AppendFormat( L"%s  ", dialog_test.str[x].GetString() );
}

xAxis.AppendFormat( L" \n%s  ", yAxis.GetString() );

特别注意,此实现调用CSimpleStringT::GetString来检索C样式字符串以与%s格式说明符一起使用。为CString占位符传递%s对象未记录为 *

另请注意,此实现使用CString对象的显式宽字符版本以及宽字符串文字。所有受支持的Windows版本都使用Unicode(UTF-16)作为其本机编码。因此,在应用程序中使用Unicode是一种自然的选择。

<小时/> * 所有当前支持的ATL / MFC版本以允许在期望C样式字符串的任何地方传递CString对象的方式实现CString。这也适用于变量参数列表。后者是实施细节,而不是记录合同的一部分。不应该依赖它。

答案 2 :(得分:1)

如果你的目标是重用变量,你可以这样做:

    geoGraph.size=limit;
    CString xAxis ="X axis: ",yAxis="Y axis: ";

    for (int x = 0; x < limit; x++)
    {

        xAxis.Format(_T("%s%i  "), CString(xAxis),(x+1));
        yAxis.Format(_T("%s%s  "), Cstring(yAxis),dialog_test.str[x]);

    }

    xAxis.Format(_T("%s \n%s  "), CString(xAxis),yAxis);

    d.SetWindowTextA(xAxis);

我有类似的情况并且它有效,因为我现在正在使用xAxis变量的副本而不是直接。

答案 3 :(得分:-1)

问题解决了。使用;

xAxis.AppendFormat(_T("\n%s  "),yAxis);