1

いくつかの連続したメモリ位置のコンテンツを印刷する小さなアプリケーションを作成しようとしています。プログラムがメモリ内のどこにあるかを示すために、メイン関数とダミー変数のメモリ位置を出力しています。

最初の列に、アドレスを出力したいと思います。2番目の列では、このアドレスの内容とその背後にある9つのアドレスの内容が必要です。3番目の列では、バイト値が印刷可能であれば、charとして出力したいと思います。印刷できない場合は、ドットを印刷したいのですが。最初の下の行では、まったく同じことをします。

起動時に、印刷する値の数を入力できます。正の値を入力するとアドレスがインクリメントし、負の値を入力するとアドレスをデクリメントします。

行きたい場所をすばやく確認するには、コードを実行し、たとえば20バイトを入力してダンプし、ダミーのアドレスを開始アドレスとして使用します。

これまでのところ、私のコードは正の値に対してのみ機能します。負の数を入力すると、セグメンテーション違反が発生しますが、その理由がわかりません。Valgrindでエラーを見つけようとしましたが、成功しませんでした。

いくつかの助けをいただければ幸いです!

これが私のコードです:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define NUMBER_OF_BYTES 10

void showAddresses(void);
void printMemory(void);
void getDumpSize(void);

char* dummy;                // dummy is een pointer naar een int
signed int dumpSize;            // how many bytes have to be dumped?
signed int upDown;          // do I need to go up or down?


int main(void)
{
    dummy = (char *) malloc (sizeof(unsigned char));// memory allocation
    showAddresses();    // prints the main function address and a variable address
    getDumpSize();  //      
    printMemory();  //
    free(dummy);        // free memory
    return 0;       // end the main function
}

void showAddresses(void)
{
    printf("Main function address is %p \n", main); 
    printf("Dummy variable address is %p \n",(void*)dummy);
}

void getDumpSize(void)
{
    printf("Enter number of bytes to dump <negative or positive>:");
    scanf("%d",&dumpSize);
    if(dumpSize<0)
    {
        upDown = -1;        // count down
        printf("upDown was set to -1\n");
    }
    else
    {
        upDown = 1;         // count up
        printf("upDown was set to +1\n");
    }
}

void printMemory(void)
{
    int input;
    printf("Enter the address:");
    scanf("%x", &input);                // enter the input
    printf("Address \tBytes \t\t\t\tChars \n"); // print the table header
    printf("--------- \t----------------------------- \t---------- ");
    int i;
    unsigned char* address;         // 
    for(i=0;i<abs(dumpSize);i++)
    {
        address = (unsigned char*) (input+(i*upDown));  // make the address to print
        if( (i%NUMBER_OF_BYTES) == 0)   // show the address every 'i*NUMBER_OF_BYTES' times
        {
            printf("\n%p \t", (void*) address); 
        }

        printf("%02x ", *address);  // print as a 2 number hex and use zero padding if needed


        if( (i%NUMBER_OF_BYTES) == (NUMBER_OF_BYTES-1) )// print the char list for every value (if printable)
        {
            printf("\t");
            int j;
            for(j=(NUMBER_OF_BYTES-1);j>=0;j--)
            {
                address = (unsigned char*) (input+(i*upDown)-j); 
                if(isprint(*address)==0)// print a dot if the byte value is not printable
                {
                    printf(".");
                }
                else
                {
                     printf("%c",*address); // print the byte value as a char, if printable
                }
            }
        }
    }
}
4

1 に答える 1

1

セグメンテーション違反は、プログラムのスコープ外のメモリにアクセスしようとしたことが原因である可能性があります。「ダミー」のアドレスは、プログラムの最初のmallocであるため、(おそらく)プログラムで使用可能なメモリの最初の「領域」を表します。そこから上に行くと、プログラムスペースに留まる可能性がありますが(したがって、セグメンテーション違反がない)、後ろに戻ると、制限されたメモリ領域に移動する可能性があります。好奇心から:「ダミー」のmallocに対して返されるメモリアドレスは何ですか?その数は、マイナスになることなく後退するのに十分な大きさですか?(プログラムに、実際のシステムメモリマップが表示されるのか、プログラム用にすでにサンドボックス化されているページマップが表示されるのか疑問に思います。)

于 2013-03-13T08:12:15.143 に答える