Im fighting a segfault error that I can't understand : I have a recursive function that expands on an array representing pixels : starting on an index, it exepands around the index to create groups of pixels by calling the same function left right up and down (aka index -1, index +1...). For debuging purposes, I have a printf call at the very first line of the function, and one just before each of the 4 recursive calls. What I dont get is, I end up with a segfault during the recursion at the recrusive call itself (I get the print that is just before the call, but not the one at function start).
void explore(Pixel * array, int j, Tache * cur_pound, int * it, Pixel previous){
printf("%d\n", j); // I DONT GET THIS PRINT AT LAST RECURSIVE CALL
// out of bounds
if(j > sizeX * sizeY)
return;
// allready explored index
if(array[j].explored == 1){
return;
}
// to big of a color difference between this pixel and the reference one
if(abs((int)array[j].r - previous.r) > SEUIL || abs((int)array[j].g - previous.g) > SEUIL || abs((int)array[j].b - previous.b) > SEUIL){
return;
}
array[j].explored = 1;
cur_pound->limits[* it] = j;
(* it)++;
// recursion
if(j +1 < sizeX * sizeY && array[j+1].explored != 1){
printf("before SF\n); // I GET THIS PRINTF
explore(array, j + 1, cur_pound, it, previous);
}
// 3 other recursive calls removed for simplicity here
}
About my data structures : a Tache * is struct that contains 3 GLubytes and limits, an int * that represents every pixel index that belongs to this group. A Pixel contains 3 GLubytes and a char that represents if this pixel has already been visited by the function. The array given to the function as the first argument is an array of Pixel that represent my image.
it is an int representing the index in the group so that my function knows where on the array it should add a new index.
Limits are initialised at -1 outside this function and are allocated with malloc(size * sizeof(int)) where size is the width of the image multiplied by its height.
This is how the inital call is done :
void taches_de_couleur(Image *i){
int j, k, y, size, it;
GLubyte * im;
Pixel * array;
sizeX = i->sizeX;
sizeY = i->sizeY;
k = 0;
size = sizeX * sizeY;
array = malloc(size * sizeof(Pixel));
im = i->data;
/* build the array from image data */
for(j = 0; j < 3 * size; j+= 3){
array[k].explored = 0;
array[k].r = i->data[j];
array[k].g = i->data[j + 1];
array[k].b = i->data[j + 2];
k++;
}
Tache * new_pound;
new_pound = malloc(sizeof(Tache));
new_pound->limits = malloc(size * sizeof(int));
int x= 0;
while(x < size){
new_pound->limits[x] = -1;
x++;
}
it = 0;
explore(array, 0, new_pound, &it, array[0]);
}
Note that the program does not produce any SF when working with small images (biggest i could do was 512x384px).
This thing has been giving me a headache for a week now, can't figure out what is causing this segfault and thats why im asking you guys if you can see anything obvious here. I can add the second function that calls explore if need be, but this part seems to be good.
EDIT : this is the output gdb gives me when I run it with a image too big :
Thread 1 "palette" received signal SIGSEGV, Segmentation fault.
0x00007ffff7b730be in __GI___libc_write (fd=1, buf=0x555555592770,
nbytes=7)
at ../sysdeps/unix/sysv/linux/write.c:26
26 ../sysdeps/unix/sysv/linux/write.c: No such file or directory.
EDIT : Since im failing to provide enough ressources, see https://github.com/BruhP8/TachesDeCouleur for the full project
Thanks in advance
What I dont get is, I end up with a segfault during the recursion at the recrusive call itself (I get the print that is just before the call, but not the one at function start).
That is an almost sure sign of stack exhaustion.
Run your program under debugger, and examine the instruction which causes segfault. Chances are, it will be one of stack manipulation instructions (CALL, PUSH), or a stack dereference instruction that follows stack decrement. You can also look at the value of $SP register, and compare it to the bounds of stack segment (from /proc/$pid/maps if you are on Linux).
The code you've shown does not appear to allocate any stack, so the problem is likely in the code you omitted.
Note that the program does not produce any SF when working with small images
That is another sign: you are probably allocating a new image on the stack, and the larger the image, the fewer levels of recursion you can achieve.
P.S. On Linux, default stack size is often 8MiB. Try ulimit -s unlimited -- if that allows the program to recur deeper, that would be a sure sign that my guess is correct. But don't use ulimit -s unlimited as a fix (it's not).
Update:
With the full source code, I was able to build the palette program. Each recursive call to explore only takes 48 bytes of stack (which isn't much).
But with default 8MiB stack, that limits the total recursion to (8 << 20) / 48 == 174762 levels deep.
TL;DR: if your recursive procedure requires one level of recursion per pixel, then you would not be able to process large images. You must rewrite the procedure to be iterative instead.
It seems the first boundary check in your code should be:
if( j >= sizeX * sizeY )
and not
if( j > sizeX * sizeY )
(As the last element of your array is array[size - 1] and not array[size])
Related
I've written a piece of code that uses a static array of size 3000.
Ordinarily, I would just use a for loop to scan in 3000 values, but it appears that I can only ever scan in a maximum of 2048 numbers. To me that seems like an issue with memory allocation, but I'm not sure.
The problem arises because I do not want a user to input the amount of numbers they intend to input. They should only input whatever amount of numbers they want, terminate the scan by inputting 0, after which the program does its work. (Otherwise I would just use malloc.)
The code is a fairly simple number occurrence counter, found below:
int main(int argc, char **argv)
{
int c;
int d;
int j = 0;
int temp;
int array[3000];
int i;
// scanning in elements to array (have just used 3000 because no explicit value for the length of the sequence is included)
for (i = 0; i < 3000; i++)
{
scanf("%d", &array[i]);
if (array[i] == 0)
{
break;
}
}
// sorting
for(c = 0; c < i-1; c++) {
for(d = 0; d < i-c-1; d++) {
if(array[d] > array[d+1]) {
temp = array[d]; // swaps
array[d] = array[d+1];
array[d+1] = temp;
}
}
}
int arrayLength = i + 1; // saving current 'i' value to use as 'n' value before reset
for(i = 0; i < arrayLength; i = j)
{
int numToCount = array[i];
int occurrence = 1; // if a number has been found the occurence is at least 1
for(j = i+1; j < arrayLength; j++) // new loops starts at current position in array +1 to check for duplicates
{
if(array[j] != numToCount) // prints immediately after finding out how many occurences there are, else adds another
{
printf("%d: %d\n", numToCount, occurrence);
break; // this break keeps 'j' at whatever value is NOT the numToCount, thus making the 'i = j' iterator restart the process at the right number
} else {
occurrence++;
}
}
}
return 0;
}
This code works perfectly for any number of inputs below 2048. An example of it not working would be inputting: 1000 1s, 1000 2s, and 1000 3s, after which the program would output:
1: 1000
2: 1000
3: 48
My question is whether there is any way to fix this so that the program will output the right amount of occurrences.
To answer your title question: The size of an array in C is limited (in theory) only by the maximum value that can be represented by a size_t variable. This is typically a 32- or 64-bit unsigned integer, so you can have (for the 32-bit case) over 4 billion elements (or much, much more in 64-bit systems).
However, what you are probably encountering in your code is a limit on the memory available to the program, where the line int array[3000]; declares an automatic variable. Space for these is generally allocated on the stack - which is a chunk of memory of limited size made available when the function (or main) is called. This memory has limited size and, in your case (assuming 32-bit, 4-byte integers), you are taking 12,000 bytes from the stack, which may cause problems.
There are two (maybe more?) ways to fix the problem. First, you could declared the array static - this would make the compiler pre-allocate the memory, so it would not need to be taken from the stack at run-time:
static int array[3000];
A second, probably better, approach would be to call malloc to allocate memory for the array; this assigns memory from the heap - which has (on almost all systems) considerably more space than the stack. It is often limited only by the available virtual memory of the operating system (many gigabytes on most modern PCs):
int *array = malloc(3000 * sizeof(int));
Also, the advantage of using malloc is that if, for some reason, there isn't enough memory available, the function will return NULL, and you can test for this.
You can access the elements of the array in the same way, using array[i] for example. Of course, you should be sure to release the memory when you've done with it, at the end of your function:
free(array);
(This will be done automatically in your case, when the program exits, but it's good coding style to get used to doing it explicitly!)
I'm trying to write a function that when given an array and a value, it checks if the value is in that array. If it is there then keep finding a new unique random value before adding it to the array. This is what I have done so far but I think the problem is my lack of understanding of pointers. Here is what I have so far:
#include <stdio.h>
#include <stdlib.h>
int getNewIndex(int index, int *visitedPixels, int *visitedPixelsIndex);
int main() {
int *visitedPixels = malloc(2 * sizeof(int));
int *visitedPixelsIndex = 0;
srand(1);
int randIndex = rand() % 16, i;
printf("Initial randIndex = %d\n", randIndex);
for(i = 0; i < 16; i++) {
randIndex = getNewIndex(randIndex, visitedPixels, visitedPixelsIndex);
printf("randIndex[%d] = %d\n", i, visitedPixels[i]);
}
return 0;
}
int getNewIndex(int index, int *visitedPixels, int *visitedPixelsIndex) {
int i = 0;
while (i < *visitedPixelsIndex) {
(index == visitedPixels[i]) ? index = rand() % 16, i = 0 : i++;
}
visitedPixels[*visitedPixelsIndex] = index;
(*visitedPixelsIndex)++;
//(*visitedPixels) = realloc(visitedPixels, (*visitedPixelsIndex+1) * sizeof(int));
return index;
}
Any help would be appreciated.
Okay, so. I'm going to try to explain with a metaphor. Hopefully it helps rather than confusing more.
Imagine memory is a long board you can write numbers on. It takes an inch of board to write a small number. Bigger numbers can be represented by writing across more slots.
An array, in our metaphor, is just a contiguous length of board you can write stuff into. If you want an array of 5 integers, and each integer takes 4 inches, you'll need 20 inches of board for it. If you wanted to pass all these integers to a function, instead of copying them all across, you would instead write down how many inches from the end of the board your array is. That's what a pointer is. It's a number telling where something is.
When you called malloc( 2 * sizeof( int ) ), you requested for a segment of the board big enough for two integers, and you received how many inches from the end of the board that new segment is. So we've got 8 inches of board X inches from the end, with X being our pointer.
Incrementing a pointer says "increase this value to point at the next element of the underlying array". A int* will increase by 4, a pointer to a structure by the size of the structure plus any alignment offset the compiler has decided for it.
It does not increase the amount of storage.
If I have a pointer to two 8 inches of board, write a 4 inch number, increment the pointer to point 4 inches more in, write another 4 inch number and increment again, my pointer is now right after the last element of the array. If I write here, all bets are off. What was on the board after the array? Who knows. It could be anything. Maybe it was a different array. Maybe it was information for keeping track of what parts of the board have been handed out to the program. Maybe it was the end of my board and I'll write off the end. Writing to memory you haven't received permission to from the operating system is where signals for "segment violations", SIGSEGV, program failures come from.
You need to request more space up front, or bigger arrays as you need them. There's also a realloc that will do this too. And for all of them, you have to check if the call failed and terminate or otherwise recover appropriately.
Hopefully this is more helpful than confusing. Good luck :)
Hi: I have been ramping up on C and I have a couple philosophical questions based on arrays and pointers and how make things simple, quick, and small or balance the three at least, I suppose.
I imagine an MCU sampling an input every so often and storing the sample in an array, called "val", of size "NUM_TAPS". The index of 'val' gets decremented for the next sample after the current, so for instance if val[0] just got stored, the next value needs to go into val[NUM_TAPS-1].
At the end of the day I want to be able to refer to the newest sample as x[0] and the oldest sample as x[NUM_TAPS-1] (or equivalent).
It is a slightly different problem than many have solved on this and other forums describing rotating, circular, queue etc. buffers. I don't need (I think) a head and tail pointer because I always have NUM_TAPS data values. I only need to remap the indexes based on a "head pointer".
Below is the code I came up with. It seems to be working fine but it raises a few more questions I'd like to pose to the wider, much more expert community:
Is there a better way to assign indexes than a conditional assignment
(to wrap indexes < 0) with the modulus operator (to wrap indexes >
NUM_TAPS -1)? I can't think of a way that pointers to pointers would
help, but does anyone else have thoughts on this?
Instead of shifting the data itself as in a FIFO to organize the
values of x, I decided here to rotate the indexes. I would guess that
for data structures close to or smaller in size than the pointers
themselves that data moves might be the way to go but for very large
numbers (floats, etc.) perhaps the pointer assignment method is the
most efficient. Thoughts?
Is the modulus operator generally considered close in speed to
conditional statements? For example, which is generally faster?:
offset = (++offset)%N;
*OR**
offset++;
if (NUM_TAPS == offset) { offset = 0; }
Thank you!
#include <stdio.h>
#define NUM_TAPS 10
#define STARTING_VAL 0
#define HALF_PERIOD 3
void main (void) {
register int sample_offset = 0;
int wrap_offset = 0;
int val[NUM_TAPS];
int * pval;
int * x[NUM_TAPS];
int live_sample = 1;
//START WITH 0 IN EVERY LOCATION
pval = val; /* 1st address of val[] */
for (int i = 0; i < NUM_TAPS; i++) { *(pval + i) = STARTING_VAL ; }
//EVENT LOOP (SAMPLE A SQUARE WAVE EVERY PASS)
for (int loop = 0; loop < 30; loop++) {
if (0 == loop%HALF_PERIOD && loop > 0) {live_sample *= -1;}
*(pval + sample_offset) = live_sample; //really stupid square wave generator
//assign pointers in 'x' based on the starting offset:
for (int i = 0; i < NUM_TAPS; i++) { x[i] = pval+(sample_offset + i)%NUM_TAPS; }
//METHOD #1: dump the samples using pval:
//for (int i = 0; i < NUM_TAPS; i++) { printf("%3d ",*(pval+(sample_offset + i)%NUM_TAPS)); }
//printf("\n");
//METHOD #2: dump the samples using x:
for (int i = 0; i < NUM_TAPS; i++) { printf("%3d ",*x[i]); }
printf("\n");
sample_offset = (sample_offset - 1)%NUM_TAPS; //represents the next location of the sample to be stored, relative to pval
sample_offset = (sample_offset < 0 ? NUM_TAPS -1 : sample_offset); //wrap around if the sample_offset goes negative
}
}
The cost of a % operator is the about 26 clock cycles since it is implemented using the DIV instruction. An if statement is likely faster since the instructions will be present in the pipeline and so the process will skip a few instructions but it can do this quickly.
Note that both solutions are slow compared to doing a BITWISE AND operation which takes only 1 clock cycle. For reference, if you want gory detail, check out this chart for the various instruction costs (measured in CPU Clock ticks)
http://www.agner.org/optimize/instruction_tables.pdf
The best way to do a fast modulo on a buffer index is to use a power of 2 value for the number of buffers so then you can use the quick BITWISE AND operator instead.
#define NUM_TAPS 16
With a power of 2 value for the number of buffers, you can use a bitwise AND to implement modulo very efficiently. Recall that bitwise AND with a 1 leaves the bit unchanged, while bitwise AND with a 0 leaves the bit zero.
So by doing a bitwise AND of NUM_TAPS-1 with your incremented index, assuming that NUM_TAPS is 16, then it will cycle through the values 0,1,2,...,14,15,0,1,...
This works because NUM_TAPS-1 equals 15, which is 00001111b in binary. The bitwise AND resulst in a value where only that last 4 bits to be preserved, while any higher bits are zeroed.
So everywhere you use "% NUM_TAPS", you can replace it with "& (NUM_TAPS-1)". For example:
#define NUM_TAPS 16
...
//assign pointers in 'x' based on the starting offset:
for (int i = 0; i < NUM_TAPS; i++)
{ x[i] = pval+(sample_offset + i) & (NUM_TAPS-1); }
Here is your code modified to work with BITWISE AND, which is the fastest solution.
#include <stdio.h>
#define NUM_TAPS 16 // Use a POWER of 2 for speed, 16=2^4
#define MOD_MASK (NUM_TAPS-1) // Saves typing and makes code clearer
#define STARTING_VAL 0
#define HALF_PERIOD 3
void main (void) {
register int sample_offset = 0;
int wrap_offset = 0;
int val[NUM_TAPS];
int * pval;
int * x[NUM_TAPS];
int live_sample = 1;
//START WITH 0 IN EVERY LOCATION
pval = val; /* 1st address of val[] */
for (int i = 0; i < NUM_TAPS; i++) { *(pval + i) = STARTING_VAL ; }
//EVENT LOOP (SAMPLE A SQUARE WAVE EVERY PASS)
for (int loop = 0; loop < 30; loop++) {
if (0 == loop%HALF_PERIOD && loop > 0) {live_sample *= -1;}
*(pval + sample_offset) = live_sample; //really stupid square wave generator
//assign pointers in 'x' based on the starting offset:
for (int i = 0; i < NUM_TAPS; i++) { x[i] = pval+(sample_offset + i) & MOD_MASK; }
//METHOD #1: dump the samples using pval:
//for (int i = 0; i < NUM_TAPS; i++) { printf("%3d ",*(pval+(sample_offset + i) & MOD_MASK)); }
//printf("\n");
//METHOD #2: dump the samples using x:
for (int i = 0; i < NUM_TAPS; i++) { printf("%3d ",*x[i]); }
printf("\n");
// sample_offset = (sample_offset - 1)%NUM_TAPS; //represents the next location of the sample to be stored, relative to pval
// sample_offset = (sample_offset < 0 ? NUM_TAPS -1 : sample_offset); //wrap around if the sample_offset goes negative
// MOD_MASK works faster than the above
sample_offset = (sample_offset - 1) & MOD_MASK;
}
}
At the end of the day I want to be able to refer to the newest sample as x[0] and the oldest sample as x[NUM_TAPS-1] (or equivalent).
Any way you implement this is very expensive, because each time you record a new sample, you have to move all the other samples (or pointers to them, or an equivalent). Pointers don't really help you here. In fact, using pointers as you do is probably a little more costly than just working directly with the buffer.
My suggestion would be to give up the idea of "remapping" indices persistently, and instead do it only virtually, as needed. I'd probably ease that and ensure it is done consistently by writing data access macros to use in place of direct access to the buffer. For example,
// expands to an expression designating the sample at the specified
// (virtual) index
#define SAMPLE(index) (val[((index) + sample_offset) % NUM_TAPS])
You would then use SAMPLE(n) instead of x[n] to read the samples.
I might consider also providing a macro for adding new samples, such as
// Updates sample_offset and records the given sample at the new offset
#define RECORD_SAMPLE(sample) do { \
sample_offset = (sample_offset + NUM_TAPS - 1) % NUM_TAPS; \
val[sample_offset] = sample; \
} while (0)
With regard to your specific questions:
Is there a better way to assign indexes than a conditional assignment (to wrap indexes < 0) with the modulus operator (to wrap
indexes > NUM_TAPS -1)? I can't think of a way that pointers to
pointers would help, but does anyone else have thoughts on this?
I would choose modulus over a conditional every time. Do, however, watch out for taking the modulus of a negative number (see above for an example of how to avoid doing so); such a computation may not mean what you think it means. For example -1 % 2 == -1, because C specifies that (a/b)*b + a%b == a for any a and b such that the quotient is representable.
Instead of shifting the data itself as in a FIFO to organize the values of x, I decided here to rotate the indexes. I would guess that
for data structures close to or smaller in size than the pointers
themselves that data moves might be the way to go but for very large
numbers (floats, etc.) perhaps the pointer assignment method is the
most efficient. Thoughts?
But your implementation does not rotate the indices. Instead, it shifts pointers. Not only is this about as expensive as shifting the data themselves, but it also adds the cost of indirection for access to the data.
Additionally, you seem to have the impression that pointer representations are small compared to representations of other built-in data types. This is rarely the case. Pointers are usually among the largest of a given C implementation's built-in data types. In any event, neither shifting around the data nor shifting around pointers is efficient.
Is the modulus operator generally considered close in speed to conditional statements? For example, which is generally faster?:
On modern machines, the modulus operator is much faster on average than a conditional whose result is difficult for the CPU to predict. CPUs these days have long instruction pipelines, and they perform branch prediction and corresponding speculative computation to enable them to keep these full when a conditional instruction is encountered, but when they discover that they have predicted incorrectly, they need to flush the whole pipeline and redo several computations. When that happens, it's a lot more expensive than a small number of unconditional arithmetical operations.
I am trying to multiply matrices of arbitrary sizes on a cortex M4-core. I DO need a malloc...
But I don't understand why at the first call it works and at the second call it doesnt work any more. it just jumps to the default interrupt handler FaultISR.
hereby the dissasembly code:
It fails when executing the BL command
function calls:
multiplyMatrices( &transFRotMatrix[0][0],3, 3, &sunMeasurements[0][0], 3, 1, *orbitalSunVector); //Works fine
multiplyMatrices( &firstRotMatrix[0][0],3, 3, &orbitalTMFV[0][0], 3, 1, *inertialTMFV); //doesn t work fine
code:
void multiplyMatrices(float *transposedMatrix, int height1, int width1, float *iSunVector,int height2, int width2, float *orbitalSunVector)
{
int y=0;
int x = 0;
int row=0;
int column =0;
int k=0;
int k2=0;
float result = 0;
float *output2=NULL;
int i=0;
int j=0;
i=0;
k=0;
k2 = 0;
if(width1 != height2)
{
//printf("unmatching matrices, error.\n\n");
return;
}
output2 = malloc(height1 * width2 * sizeof(float)); //<---- jumps o FaultISR
while(k<width1) //aantal rijen 1ste matrix
{
for(j=0;j<height2;j++) //aantal rijen 2de matrix
{
result += (*((transposedMatrix+k*width1)+j)) * (*((iSunVector+j*width2)+k2)); //1ste var:aantal kolommen 2de matrix --2de variabele na de plus = aantal kolommen 2de matrix
//printf("%f * %f\t + ", (*((transposedMatrix+k*width1)+j)), (*((iSunVector+j*width2)+k2)));
}
output2[row* width1 + column] = result;
k2++;
x++;
column++;
if(x==width2) //aantal kolommen 2de Matrix
{
k2=0;
x=0;
column=0;
row++;
y++;
k++;
}
result = 0;
}
//tussenresultaat
for(i=0;i<height1;i++)
{
for(j=0;j<width2;j++)
{
orbitalSunVector[j * height1 + i] = output2[i* width1 + j]; //output2[i][j];
}
}
free(output2);
}
You are overflowing your output2 matrix in both loops due to an incorrect index calculation. You have:
output2[row*width1 + column] = result;
...
orbitalSunVector[j*height1 + i] = output2[i*width1 + j];
but you should be using width2 in both cases since the final matrix is width2 * height1 in size (as it is allocated):
output2[row*width2 + column] = result;
...
orbitalSunVector[j*height1 + i] = output2[i*width2 + j];
I didn't check any of your other indexes but I would test the function with a few known cases to make sure it outputs the correct results. If you had done more debugging and checked the array indexes it should have been easy to spot.
Note that the reason it worked for you the first time but not the second time is due to undefined behaviour (UB). As soon as you write past the end of output2 you invoke UB and anything can happen. For you it happened to show up as a fault on the second call. For me it happened to fault on the first call. If you're really unlucky it may not ever fault and just silently corrupt data.
Do you use printf in other places of your code?
This page recommends starting at 0x400 for heap size, which is 1024 decimal:
It is recommended to start with a reasonable heap size like 0x400 when
there is limited dynamic allocation (like printf() calls in the code),
and increase it as needed depending on the application.
You have 512 today, you could at least try to double that if possible, as per TI's recommendation, and see where this leads you.
This is a related question. If you do not have a tool to watch heap allocation on the fly, try to manually fill the heap at startup (memcpy it with known values, such as ASCII '#==#', 0xDEADBEEF, or whatever recognizable value), then run to just before you usually crash, and watch the content of the heap in the Memory window. My best guess is that you'll find the heap is full.
Please also look if you can see error flag registers while you are in the FaultISR. Often there is something somewhere telling you why you came here.
I am not sure about TI's implementation of malloc, but they may save an error value. I'd not bet on that one, since it would probably return NULL in that case, rather than crash.
I'm attempting a C programming assignment where I need to iterate through each index of each line of a document, and set an integer value at each character index in a corresponding array ar:
//Jagged array ar containing pointers to each row
int* ar[line_count];
//The size of each row is the line width * the size of an int ptr
const int line_size = max_width * sizeof(int*);
//For each line
for (i = 0; i < line_count; i++)
{
//If the first runthrough, copy the blank array
if (i == 0)
{
ar[i] = malloc(line_size);
memcpy(ar[i], blank_ar, line_size);
}
//Otherwise, copy from the last row
else
{
ar[i] = malloc(line_size);
//This is set to a null pointer after several runthroughs
memcpy(ar[i], ar[i - 1], line_size);
}
//Edit the current row ar[i]
}
The only problem is, after some 9 iterations, malloc starts returning a null pointer that causes memcpy to (obviously) not work.
Is there any reason this is happening? There is no way I'm running out of memory as I only allocate these tiny arrays 9 times.
malloc will return the null pointer when it fails. Some obvious reasons why this could happen:
You have exhausted heap memory. That is plausible if line_size is very large.
You have corrupted the heap. That could happen if there are errors in the code that you are running, but have removed for the purpose of asking this question.
Inspect the value of errno to find out more information about the failure.
Maybe you stack is too little, try to modify the default stack at compile/linking time in your IDE. If you are using GCC take a look into this Change stack size for a C++ application in Linux during compilation with GNU compiler