函数抛出写访问异常

时间:2017-12-29 09:00:52

标签: c++ c exception access-violation

我正在阅读一篇文章或在线发帖:Eli Bendersky's Website : Binary Representation of Big Numbers并遇到了一个函数,所以我决定在我的IDE中测试它。功能编译&构建,但是当我运行代码时,它想要抛出异常:写入访问冲突。

这是功能:

/* Note: in and out may be the same string,
   it will still work OK
*/
void longdiv2(const char* in, char* out)
{
    int carry = 0;

    while (*in)
    {
        int numerator = *in++ - '0';
        numerator += carry;

        carry = (numerator % 2) == 0 ? 0 : 10;
        *out++ = '0' + (numerator / 2);
    }

    *out = '\0';
}

我这样用:

#include <iostream>

int main() {
    char* value = "12345";
    char* binResult = '\0';

    longdiv2( value, binResult );

    std::cout << *binResult << std::endl;

    std::cout << "\nPress any key and enter to quit." << std::endl;
    char q;
    std::cin >> q;

    return 0;
}

此行上会引发访问冲突:

 *out++ = '0' + (numerator / 2);

违规行为表明outnullptr

我在运行Win7 Home Premium x64的Intel Quad Core Extreme上的MS Visual Studio 2017 CE上运行此程序 - 编译并构建为x86控制台应用程序。

[注意:]我用C&amp;标记了这个C ++:我这样标记它是因为文章提到他们为C编写它,但是我在C ++中使用相同的函数。

2 个答案:

答案 0 :(得分:3)

*out++正在访问未指向有效内存的指针。这就是为什么在进行非法内存访问后取消引用时会出现访问冲突的原因。这可以工作

char binResult[10];

这里基本上当你将它传递给函数时,你将传递腐朽的char*并对其进行更改。

或者也可以这样做

binResult =(char*) malloc(10);
if( binResult == NULL){
  perror("Malloc Failed");
}
  

详细地说,问题归结为 指针不是   指向可以存储结果的任何缓冲区 。当你尝试   要访问它,你基本上是想写一些内存   你甚至没有得到许可。 ( 写入访问冲突 )。那&#39; S   为什么你得到错误。

更清楚的是,当您将指针值设置为\0然后尝试访问它时,不应该感到惊讶。在第一次迭代时,它会导致nullptr访问,从而导致错误。

完整C代码:

#include<stdio.h>
void longdiv2(const char* in, char* out)
{
    int carry = 0;

    while (*in)
    {
        int numerator = *in++ - '0';
        numerator += carry;

        carry = (numerator % 2) == 0 ? 0 : 10;
        *out++ = '0' + (numerator / 2);
    }

    *out = '\0';
}


int main(void) {
    char* value = "12345";
    char binResult[10];

    longdiv2( value, binResult );

    printf("%s\n",binResult);
    return 0;
}

此输出

06172

使用gcc 6.3.0编译的代码:gcc -Wall -Werror progname.c

C++解决方案就像

/* Here in and out shouldn't point to same thing */

#include <iostream>
#include <string>

void longdiv2(std::string in, std::string& out)
{
    int carry = 0;

    for(auto x:in)
    {
        int numerator = x - '0';
        numerator += carry;

        carry = (numerator % 2) == 0 ? 0 : 10;
        out.push_back( '0' + (numerator / 2));
    }

}

int main(void) {
    std::string value = "12345";
    std::string binResult;

    longdiv2( value, binResult );

    std::cout<<binResult<<std::endl;
    return 0;
}

答案 1 :(得分:1)

更改以下内容:

char* binResult = '\0';

为:

char binResult[10] {};