简体   繁体   English

基本C矩阵分段内存分配

[英]Basic C Matrix segmentation memory allocation

I tried to run this program through the terminal and this error showed up. 我试图通过终端运行该程序,但出现此错误。 "Segmentation Fault: 11" “分段错误:11”

I would like to know why . 我想知道为什么 。 What this program does is, it reads a .ppm file and it saves it's information in a matrix variable of type Pixel, so, a PPM file is basically composed by: the first line is going to be "P3" by default, second line the size of the matrix, and the third line the highest value possible for a Pixel attribute, the other lines will have 3 integers of maximum value of 255, so for each member of the matrix there will be a pixel R, G, B. what I tried to do in the function save_image, first recognize if we are dealing with a ppm file(checking if there is a P3 in the first line), then read the number of rows and columns for the matrix, then it creates a new matrix using the malloc function, then it will save the data in the lines of the file to the .r and .g and .b of the variable myImg. 该程序的作用是,读取一个.ppm文件,并将其信息保存在Pixel类型的矩阵变量中,因此,一个PPM文件基本上由以下组成:第一行默认为“ P3”,第二行矩阵的大小,第三行为Pixel属性可能的最大值,其他行将具有3个最大值为255的整数,因此对于矩阵的每个成员,将有一个像素R,G,B。我在函数save_image中尝试执行的操作,首先识别我们是否正在处理ppm文件(检查第一行中是否存在P3),然后读取矩阵的行数和列数,然后创建一个新的使用malloc函数创建矩阵,然后将文件行中的数据保存到变量myImg的.r和.g和.b中。 I am very new to debugging/programming so I'm sorry if this isn't enough information but I tried my best. 我对调试/编程非常陌生,因此,如果信息不足,我们感到很抱歉,但我已尽力了。

#include <stdio.h>
#include <stdlib.h>
typedef struct{
    int r;
    int g;
    int b;
}Pixel;

void save_image(FILE* img, Pixel ** newImg) {
    int i;
    int j;
    int fcount;
    int scount;
    int count;
    int dcc;
    char init[3];
    fscanf(img,"%s",init);
    if(init[0]=='P' && init[1]=='3'){
        printf("worked!\n");
        fscanf(img,"%d %d",&j,&i);
        fscanf(img, "%d",&dcc);
        *newImg = (Pixel*)malloc(sizeof(Pixel) * i);
        for ( count = 0; count < i ; ++count)
        {
            newImg[count] = (Pixel*)malloc(sizeof(Pixel) * j);
        }
        for (fcount = 0; fcount <= i ; ++fcount)
        {
         for (scount = 0; scount <= j; ++scount)
         {
            fscanf(img,"%i %i %i",&newImg[i][j].r,&newImg[i][j].g,&newImg[i][j].b);
         }
        }
    }
    else 
        printf("Type of file not recognized\n");

    fclose(img);
}


int main(int argc, char const *argv[])
{
    FILE* image;
    Pixel myImg;
    Pixel** newImg;
    **newImg = myImg;
    image = fopen(argv[1],"r");
    save_image(image,newImg);
    return 0;
}

The program fails because the initial malloc for newImg[] is malloc'ing some multiple of the size of Pixel rather than size of pointer to Pixel combined with problems with the passing of the pointer to the newImg as a parameter to the save_image() function. 程序失败,因为针对newImg []的初始malloc正在malloc分配Pixel大小的某些倍数,而不是指向Pixel的指针大小,再加上将newImg指针作为save_image()函数的参数传递问题。 See my comment about where the variable newImg should be defined and the desirable modification to the declaration of the save_image() function 请参阅我的评论,其中应在哪里定义变量newImg以及对save_image()函数的声明进行适当的修改

Given the was the posted code is written, it seems to be expecting the 'plain' .ppm file format 鉴于已编写了发布的代码,因此似乎期望使用“普通” .ppm文件格式

and the posted code is failing to allow for any embedded comments within the file 并且发布的代码无法允许文件中包含任何嵌入的注释

given this description of the format of a .ppm file: 给出了.ppm文件格式的描述:

The format definition is as follows. 格式定义如下。 You can use the libnetpbm C subroutine library to read and interpret the format conveniently and accurately. 您可以使用libnetpbm C子例程库方便,准确地读取和解释该格式。

A PPM file consists of a sequence of one or more PPM images. 一个PPM文件由一个或多个PPM图像序列组成。 There are no data, delimiters, or padding before, after, or between images. 图像之前,之后或之间没有数据,定界符或填充。

Each PPM image consists of the following: 每个PPM映像均包含以下内容:

A "magic number" for identifying the file type. A ppm image's magic number is the two characters "P6".
Whitespace (blanks, TABs, CRs, LFs).
A width, formatted as ASCII characters in decimal.
Whitespace.
A height, again in ASCII decimal.
Whitespace.
The maximum color value (Maxval), again in ASCII decimal. Must be less than 65536 and more than zero.
A single whitespace character (usually a newline).
A raster of Height rows, in order from top to bottom. Each row consists of Width pixels, in order from left to right. Each pixel is a triplet of red, green, and blue samples, in that order. Each sample is represented in pure binary by either 1 or 2 bytes. If the Maxval is less than 256, it is 1 byte. Otherwise, it is 2 bytes. The most significant byte is first.

A row of an image is horizontal. A column is vertical. The pixels in the image are square and contiguous.

In the raster, the sample values are "nonlinear." They are proportional to the intensity of the ITU-R Recommendation BT.709 red, green, and blue in the pixel, adjusted by the BT.709 gamma transfer function. (That transfer function specifies a gamma number of 2.2 and has a linear section for small intensities). A value of Maxval for all three samples represents CIE D65 white and the most intense color in the color universe of which the image is part (the color universe is all the colors in all images to which this image might be compared).

ITU-R Recommendation BT.709 is a renaming of the former CCIR Recommendation 709. When CCIR was absorbed into its parent organization, the ITU, ca. 2000, the standard was renamed. This document once referred to the standard as CIE Rec. 709, but it isn't clear now that CIE ever sponsored such a standard.

Note that another popular color space is the newer sRGB. A common variation on PPM is to substitute this color space for the one specified.

Note that a common variation on the PPM format is to have the sample values be "linear," i.e. as specified above except without the gamma adjustment. pnmgamma takes such a PPM variant as input and produces a true PPM as output. 

Strings starting with "#" may be comments, the same as with PBM. 与“ PBM”相同,以“#”开头的字符串可能是注释。

Note that you can use pamdepth to convert between a the format with 1 byte per sample and the one with 2 bytes per sample. 请注意,您可以使用pamdepth在每个样本1字节的格式和每个样本2字节的格式之间进行转换。

All characters referred to herein are encoded in ASCII. 本文所指的所有字符均以ASCII编码。 "newline" refers to the character known in ASCII as Line Feed or LF. “换行符”是指ASCII中称为换行符或LF的字符。 A "white space" character is space, CR, LF, TAB, VT, or FF (Ie what the ANSI standard C isspace() function calls white space). “空白”字符是空格,CR,LF,TAB,VT或FF(即ANSI标准C isspace()函数称为空白)。 Plain PPM 普通PPM

There is actually another version of the PPM format that is fairly rare: "plain" PPM format. 实际上,还有另一种相当罕见的PPM格式版本:“普通” PPM格式。 The format above, which generally considered the normal one, is known as the "raw" PPM format. 上面通常被认为是正常格式的格式称为“原始” PPM格式。 See pbm for some commentary on how plain and raw formats relate to one another and how to use them. 有关纯格式和原始格式如何相互关联以及如何使用它们的注释,请参见pbm。

The difference in the plain format is: 普通格式的区别是:

There is exactly one image in a file.
The magic number is P3 instead of P6.
Each sample in the raster is represented as an ASCII decimal number (of arbitrary size).
Each sample in the raster has white space before and after it. There must be at least one character of white space between any two samples, but there is no maximum. There is no particular separation of one pixel from another -- just the required separation between the blue sample of one pixel from the red sample of the next pixel.
No line should be longer than 70 characters. 

Here is an example of a small image in this format. 这是这种格式的小图像的示例。

 P3
 # feep.ppm
 4 4
15
 0  0  0    0  0  0    0  0  0   15  0 15
 0  0  0    0 15  7    0  0  0    0  0  0
 0  0  0    0  0  0    0 15  7    0  0  0
15  0 15    0  0  0    0  0  0    0  0  0

There is a newline character at the end of each of these lines. 每行的末尾都有一个换行符。

Programs that read this format should be as lenient as possible, accepting anything that looks remotely like a PPM image. 读取此格式的程序应尽可能宽松,接受看起来像PPM映像的任何内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM