0

So as the title says, I'm trying to do the pset4 where I get this error when I try to execute the program. I've searched the forum and also Reddit, and I understood that I've some issue with the malloc(). I found that when I get this type of error, it means that I'm not allocating enough memory to my pointer. I'm sorry if this question has been answered or if it's too silly, but I'm stuck on this error for 5 consecutive days. So here is my code and I'd be more than happy if someone could makes me see what I'm doing wrong. Thank you for your time!

    // Copies a BMP file

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

#include "bmp.h"

int main(int argc, char *argv[])
{
    // ensure proper usage
    if (argc != 4)
    {
        fprintf(stderr, "Usage: copy infile outfile\n");
        return 1;
    }

    // remember filenames
    int n = atoi(argv[1]);
    char *infile = argv[2];
    char *outfile = argv[3];

    // check if n is correct
    if (n < 0 || n > 100)
    {
        fprintf(stderr, "n must be a positive integer less than or equal to 100\n");
        return 1;
    }

    // open input file
    FILE *inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return 1;
    }

    // open output file
    FILE *outptr = fopen(outfile, "w");
    if (outptr == NULL)
    {
        fclose(inptr);
        fprintf(stderr, "Could not create %s.\n", outfile);
        return 1;
    }

    // read infile's BITMAPFILEHEADER
    BITMAPFILEHEADER bf;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

    // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi;
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

    // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
    if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
        bi.biBitCount != 24 || bi.biCompression != 0)
    {
        fclose(outptr);
        fclose(inptr);
        fprintf(stderr, "Unsupported file format.\n");
        return 2;
    }

    // determine padding for scanlines
    int infilePadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // update output file's header info while keeping the old one
    int infileBiWidth = bi.biWidth;
    int infileBiHeight = bi.biHeight;
    bi.biWidth *= n;
    bi.biHeight *= n;

    // use malloc for creating memory to store pixels of outfile
    RGBTRIPLE* ppixel = malloc(sizeof(RGBTRIPLE) * bi.biWidth);

    // create a variable for keeping track of ppixelIndex
    int ppixelIndex = 0;

    // calculate padding bytes for output file
    int outfilePadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // recalculate header info
    bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + outfilePadding) * abs (bi.biHeight);
    bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    // write outfile's BITMAPFILEHEADER
    fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);

    // write outfile's BITMAPINFOHEADER
    fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);

    // iterate over infile's scanlines
    for (int i = 0; i < abs(infileBiHeight); i++)
    {
        // iterate over pixels in scanline
        for (int j = 0; j < infileBiWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

            // read RGB triple from infile
            fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

            // store each pixel n times to ppixel
            for (int l = 0; l < n; l++)
            {
               ppixel[ppixelIndex] = triple;
               ppixelIndex++;
            }
        }

        // for each pixel write it n times
        for (int m = 0; m < n; m++)
        {
            for (int p = 0; p < n; p++)
            {
                // write RGB triple to outfile
                fwrite(&ppixel[p], sizeof(RGBTRIPLE), 1, outptr);
            }

            // write outfile's padding
            for (int k = 0; k < outfilePadding; k++)
            {
                fputc(0x00, outptr);
            }
        }

        // skip over infilePadding, if any
        fseek(inptr, infilePadding, SEEK_CUR);
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // free ppixel
    free (ppixel);

    // success
    return 0;
}
1
  • Thanks @MARS for helping me out with the format. It was my first post, apologies...
    – Dement0
    Commented May 21, 2018 at 5:49

1 Answer 1

1

I think I found the answer. The main problem was that I was setting the ppixelIndex variable out of the for loop and I was incrementing it way too much. So when the first iteration for the first row finishes, I wasn't resetting it so during the second iteration I was trying to reach the memory that wasn't allocated. I've also modified my code a little bit, but the main solution was moving the ppixelIndex variable to inside of the loop. Hope this solution helps someone :)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .