C语言 为什么在我的主函数运行之前,我会出现分段错误(核心转储)

z8dt9xmd  于 2023-03-28  发布在  其他
关注(0)|答案(3)|浏览(141)

我是一个C新手,我写了一个相对简单的赋值代码,它应该从一个文件中逐个字节地获取输入,并打印一个十六进制值的表,类似于-od命令。我把所有的代码都移到了一个文件中,包括在这里。

#include <stdio.h>
#include "dataDump.h"

//
// Created by crsan on 3/23/2023.
//
#include "dataDump.h"
int dataDump(char *fileName) {
    FILE *inFile = fopen(fileName, "r");
    if (inFile == NULL) {
        return -1;
    }
    int whiteSpace = 00000000;
    int line = 0;
    unsigned char c;

    printf("00000000");
    char *hex = NULL;
    for (int i = 0; (c = getc(inFile)) != EOF; i++) {
        sprintf(hex, "%02x", c);
        printf(" %s", hex);
        whiteSpace++;
        line++;
        if (line == 15) {
            printf("\n%08d", whiteSpace);
            line = 0;
        }

    }
    if (line != 0) {
        printf("\n%d", whiteSpace);
    }
    return whiteSpace;
}
int main(int argc, char *argv[]) {
    printf("test words");
    dataDump(argv[1]);
    return 0;
}

然而,甚至在main函数的print语句之前,存在分段错误,并且代码无法进一步编译。
这应该是使用UNIX命令行输入编译的,我不熟悉,可能是错误的原因,除此之外,谷歌告诉我,这可能是内存分配错误,我还没有了解到这一点。我在想的另一种可能性可能是我用来改成十六进制的sprintf。如果任何人以前遇到过这种情况或有任何想法的原因可能是任何援助将不胜感激。

quhf5bfb

quhf5bfb1#

最可能的错误原因是尝试使用sprintf打印到NULL缓冲区。

char *hex = NULL;
   for (int i = 0; (c = getc(inFile)) != EOF; i++) {
       sprintf(hex, "%02x", c);
       printf(" %s", hex);

此缓冲区的内存不是由sprintf分配的。您需要为null终止符留出空间,因此可以指定一个char数组,其中包含8个char值,这将轻松处理您想要保存的值:

char hex[8];
    for (int i = 0; (c = getc(inFile)) != EOF; i++) {
        sprintf(hex, "%02x", c);
        printf(" %s", hex);

正如注解中所指出的,构造值的字符串表示,然后将该字符串打印到标准输出是不必要的。

for (int i = 0; (c = getc(inFile)) != EOF; i++) {
        printf(" %02x", c);
plupiseo

plupiseo2#

你几乎肯定不会在“主函数的任何部分运行之前”得到分段错误。分段错误发生在稍后,但由于缓冲,你看不到任何来自printf的输出。printf并不总是将数据写入输出流。相反,printf将数据存储在内部缓冲区中,并且仅偶尔写入该数据。何时可以发生写入的细节对于这个问题并不特别重要,但原因应该是理解的。写入数据可能是昂贵的,所以标准库实现推迟写入,直到有足够的数据可用,使其值得。有3个标准缓冲模式:全缓冲(又名块缓冲)、行缓冲和非缓冲。如果流是非缓冲的,则printf将始终写入数据。如果流是行缓冲的,则printf将在向缓冲区添加整行时写入数据。对于块缓冲,printf将延迟写入,直到完成数据块(例如4096字节)可用。您可以通过在流上调用fflush来触发写操作。因此,如果您想确保看到文本,可以执行以下操作:

printf("test words");
fflush(stdout);

通常,当程序退出时,缓冲区被刷新,但如果程序异常终止,则并不总是发生这种情况。分段错误会导致异常终止,并且缓冲区不会被刷新。
注意,如果流是行缓冲的,你可能会使用printf("test words\n")puts("test words")而不是显式调用fflush。一位评论者认为这是足够的,因为“stdout是面向行的”,但这并不总是正确的。stdout通常是行缓冲的,但并不总是如此。如果你想确保数据被写入,显式的fflush是明智的。

ruarlubt

ruarlubt3#

这演示了一种实现你需要的东西的方法。它没有涵盖你编码的所有东西,但涵盖了你定义的目标的基础。希望它足以帮助回答你的问题。祝你好运。

#include <stdio.h>

int main()
{
    char value; // used to read the data one character (char is 1 byte) at a time.

    // create a file named test.txt & save some data in it.
    FILE * outFile; // define a pointer to File named outFile
    outFile = fopen("test.txt", "w"); // create a file named test.txt, open it in write mode.
    
    fprintf(outFile, "abcdefghivklmnopqrstuvwxyz1234567890\r\n"); // send some data to the file
    
    fclose(outFile); // close the file

    // open test.txt in read mode, read the data one char (byte) at a time & print it out.
    FILE * inFile; // define a pointer to File named inFile
    inFile = fopen("test.txt", "r"); // open a file named test.txt in read mode.
    
    while(1) // create a non-ending loop. we'll break out of it when we're finished reading the file.
    {
        value = fgetc(inFile); // get char from test.txt one byte at a time 
    
        if(feof(inFile)) // break the loop when we areat the end of the file.
            break;
    
        printf("%02x ",value); // print each char as hex
    }
    fclose(inFile); // colse inFile

    printf("\n"); // put a line break at the end of the printed data.

    return 0;
}

相关问题