2017-12-29 75 views
1

ここで記事を読んでいたか、オンラインで投稿しました: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であった。


私はMSのVisual Studio上でwin7のホームプレミアムのx64を実行しているIntelのクアッドコアExtremeの2017 CE、これを実行している - コンパイルおよびx86コンソールアプリケーションとして構築されています。

[注:]:記事は、彼らはCのためにそれを書かれたことを述べたので、私は、このようにそれをタグ付けされたが、私はC++で同じ機能を使用しています私はC & C++の両方でこれをタグ付け。

+1

すでに負の評論家... –

+2

'のchar * binResult = '\ 0';' '効果的に文字を書くことと同じです* binResult = nullptr; ' – user0042

+1

ダウンポットに注意してください。ちょうど 'char * binResult = '\ 0';'間違って間違って間違っている –

答えて

3

*out++は有効なメモリを指していないポインタにアクセスしています。そのため、不正なメモリアクセスが発生した後で、アクセス違反が発生した場合に参照違反が発生します。あなたが朽ち果てchar*を渡すと、それに変更を加えることになる関数に渡すとき、これは基本的にここで

char binResult[10]; 

を働くだろう。

また、これはまた、詳細には

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

を行います、問題がポインタを使用すると、結果を格納できる任意のバッファを指していない たことに帰着します。 にアクセスしようとすると、基本的にいくつかのメモリに書き込むことを試みていました。 あなたには権限がありません。 (書き込みアクセス違反)。それは なので、エラーが発生します。

ポインタ値を\0に設定してからアクセスしようとすると、それは驚きではありません。最初の反復自体では、エラーの原因となるのはnullptrになります。

Cコード: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; 
} 
のようになります。

#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; 
} 

これはgcc 6.3.0を使用してコンパイル

06172 

コードを出力

1

変更以下:

char* binResult = '\0'; 

へ:説明なし

char binResult[10] {}; 
+0

(これもコンパイルしてはいけません):いいえ、それは整数値です。たぶん警告ですが、ポインタを効果的に0に設定します –

+0

'char * binResult = '\ 0';'はなぜコンパイルしないと思いますか?それは完全に有効です。 – user0042

+0

私は既に私の質問で "コンパイル&ビルド"を行っていると述べています。実行時に例外がスローされました。私はランタイム例外が何であるかを知っています:私のCは少し錆びていて、 'C'スタイルの文字列を優先する' C++ '' std :: string'よりも何が起こっていたのか覚えていました... –

関連する問題