函数抛出写访问异常[关闭]

问题描述 投票:1回答:2

我正在阅读一篇文章或在线发帖: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&C ++标记了这个:我这样标记它是因为文章提到他们为C编写它,但是我在C ++中使用相同的函数。

c++ c exception access-violation
2个回答
3
投票

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

char binResult[10];

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

或者这也可以

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

详细地说,问题归结为指针没有指向可以存储结果的任何缓冲区。当你试图访问它时,你基本上试图写入一些你甚至没有权限的内存。 (写入访问冲突)。这就是你得到错误的原因。

更明确的是,当您将指针值设置为\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
投票

更改以下内容:

char* binResult = '\0';

至:

char binResult[10] {};
© www.soinside.com 2019 - 2024. All rights reserved.