I am trying to learn graphics programming and I have written a simple OpenGL program that draws a triangle and should shade it red, however when I call the function glShaderSource for the the fragment shader it causes a segfault.
I don't know why it causes a segfault because the spec page doesn't say anything about the function causing a segfault, and anything about the shaders being loaded into memory wrong can't be it either, as the vertex shader is loaded in the same way and when I call glGetShaderInfoLog and print the log it says the vertex shader compile fine.
Anyways heres my code that Loads the shaders and links the shading program...
int LoadShader(char* Filename, GLchar* ShaderSource) //dont call this function by itself as it doesnt free its own memory
{
FILE* z;
z = fopen(Filename, "rb");
if(z == NULL) {printf("Error: file \"%s\" does not exist...\n", Filename); return -1;}
unsigned long len = 0;
//get file length
fseek(z, 0, SEEK_END);
len = ftell(z);
rewind(z);
if(len == 0) {printf("Error reading file \"%s\"\n", Filename); return -1;}
ShaderSource = (char*)malloc((sizeof(char)) * len + 1); //allocate enough bytes for the file
if(ShaderSource == NULL) {puts("Memory Error"); return -1;}
size_t result = fread(ShaderSource, 1, len, z);
if( result != len)
{
puts("Reading Error");
free(ShaderSource);
ShaderSource = NULL;
return -1;
}
ShaderSource[len] = 0; //make it null terminated
puts(ShaderSource); //debbugging
fclose(z);
return 1;
}
//----------------------------------------------------------------------
GLuint MakeProgram(char* VSpath, char* FSpath){
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
GLchar* VSsource;
GLchar* FSsource;
if(!LoadShader(VSpath, VSsource))
return -1;
if(!LoadShader(FSpath, FSsource))
return -1;
GLint Result = GL_FALSE;
int InfoLogLength;
//compile shaders
const char* VS = VSsource; // glShaderSource needs a const char
glShaderSource(VertexShaderID, 1, &VS, NULL); //we use NULL for length becuase the source is null-terminated
glCompileShader(VertexShaderID);
//check
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char* VSerr;
VSerr = (char*)malloc(sizeof(char) * InfoLogLength);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VSerr[0]);
printf("%s\n", VSerr);
free(VSerr);
VSerr = NULL;
//fragment shader
const char* FS = FSsource;
glShaderSource(FragmentShaderID, 1, &FS, NULL);
glCompileShader(FragmentShaderID);
//check
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char* FSerr;
FSerr = (char*)malloc(sizeof(char) * InfoLogLength);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FSerr[0]);
printf("%s\n", FSerr);
free(FSerr);
FSerr = NULL;
//link program
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
//check program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char* err;
err = (char*)malloc(sizeof(char) * InfoLogLength);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &err[0]);
printf("%s\n", err);
free(err);
//free the shaders
free(VSsource);
VSsource = NULL;
free(FSsource);
FSsource = NULL;
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
Take a closer look at your actual declarations of VSsource (uninitialized), FSsource (uninitialized) and the implementation of LoadShader (...). Because this is C and you do not pass things by reference any changes made to the ShaderSource pointer inside the LoadShader (...) function as you originally wrote it will not propagate outside the function.
In short, you implemented LoadShader (...) incorrectly. You need to actually change the address stored in the pointer you pass it (since you are allocating this memory inside the function), but you cannot do that since you currently pass it a GLchar*.
As for why GL accepts an uninitialized pointer for your first call to glShaderSource (...) I cannot say. Perhaps you are just extremely lucky? Regardless, you can correct your issue by altering LoadShader to take a GLchar** instead. I will illustrate the necessary changes below:
/* Originally, you made a copy of an uninitialized pointer and then proceeded to
re-assign this copy a value when you called malloc (...) - you actually need
to pass a pointer to your pointer so you can update the address outside of
this function!
*/
int LoadShader(char* Filename, GLchar** pShaderSource) //dont call this function by itself as it doesnt free its own memory
{
[...]
*pShaderSource = (GLchar *)malloc((sizeof(GLchar)) * len + 1); //allocate enough bytes for the file
GLchar* ShaderSource = *pShaderSource;
[...]
}
GLuint MakeProgram(char* VSpath, char* FSpath){
[...]
GLchar* VSsource; /* Uninitialized */
GLchar* FSsource; /* Uninitialized */
if(!LoadShader(VSpath, &VSsource)) /* Pass the address of your pointer */
return -1;
if(!LoadShader(FSpath, &FSsource)) /* Pass the address of your pointer */
return -1;
/*
* Now, since you did not pass copies of your pointers, you actually have
* *VALID* initialized memory addresses !
*/
[...]
}
Alternatively, you could simply modify your function to return the address of the string you allocated. Instead of returning -1 on failure like you do now, you could return NULL. Your function interface would be as simple as this if you chose to go that route: GLchar* LoadShader (char* Filename).
Related
I don't understand how the freeing is working. I know this happens when I try to free memory twice. However, this is really stumping me.
I've tried to post just the relevant parts of the code.
FILE* file = fopen(path, "r");
if (file == NULL)
{
error(500);
return;
}
// load file's content
BYTE* content;
size_t length;
if (load(file, &content, &length) == false)
{
error(500);
return;
}
This is the load fucntion
bool load(FILE* file, BYTE** content, size_t* length)
{
printf("\nLOAD STARTED\n");
content = NULL;
BYTE *data = NULL;
int size = 0;
while(!feof(file))
{
char ch = fgetc(file);
size += 1;
data = realloc(data, sizeof(BYTE) * (size));
*(data + (size - 1)) = ch;
}
content = &data;
*length = size;
printf("\nLOAD ENDED\n");
return true;
}
A little while later I'm calling free()
printf("\nFREEING CONTENT\n");
// free file's content
free(content);
printf("\nCONTENT FREED\n");
The printf statement FREEING CONTENT works after which I get the
munmap_chunk(): invalid pointer error.
This is the problem:
content = &data;
It assigns the address of a local variable that goes out of scope after the function returns. Since content is a function parameter, nothing gets written to where it points. Did you mean to write
*content = data;
instead? If so you, you should not set content = NULL because you want to use the address passed by the call load(file, &content, &length).
I managed to fix it.
content was basically just a char*. So, I tried this and it worked...
I changed content = &data to content = &(data[0])
It works. Appreciate all the inputs. :D
So I have the following question:
I have this struct ListAut
struct ListAut{
char* biggestn;
int sizeof_biggestn;
int total_len;
struct node* avl;
};
Its typedef is as it follows:
typedef struct ListAut *IndexOfAuts;
IndexOfAuts *newIndexOfAuts()
{
int i;
IndexOfAuts *ioa = malloc(27 * sizeof(struct ListAut));
for (i = 0; i < 27; i++)
{
ioa[i]->biggestn = "";
ioa[i]->sizeof_biggestn = 0;
ioa[i]->total_len = 0;
ioa[i]->avl = NULL;
}
return ioa;
}
void insertName(IndexOfAuts * ioa, char *nome)
{
char *aux = malloc(sizeof(nome));
aux = trim(nome);
int index = getIndexOfLetter(aux);
if (nameLen(aux) > getSizeOfLongName(ioa[index]))
{
strcpy(ioa[index]->biggestn, aux);
ioa[index]->sizeof_biggestn = nameLen(aux);
}
ioa[index]->total_len += nameLen(aux);
insert(ioa[index]->avl, aux);
}
This is an important part of a module I need for a project, and on its main it's Seg Faulting. I suspect it's on the creation of an "object" newIndexOfAuts(),
The idea of this module is to have an array of 27 pointers to those structures, one to each letter and another to the special characters;
Now I'm just confused because it might be from the problem above or from a module loader I made:
void loadModules(char *filename, IndexOfAuts * ioa, StatTable st)
{
char *nameofile = malloc(20);
strcpy(nameofile, filename);
FILE *file = fopen(nameofile, "r");
if (file != NULL)
{
int counter, ano;
char *buff, *field, *auxil;
buff = malloc(1024);
field = malloc(200);
auxil = malloc(200);
while (fgets(buff, 1024, file))
{
counter = 0;
field = strtok(buff, ",");
printf("inserting 1st name\n");
insertName(ioa, field);
counter++;
while (!atoi(field))
{
if ((auxil = strtok(NULL, ",")) != NULL)
{
counter++;
field = auxil;
insertName(ioa, field);
}
}
ano = atoi(field);
incPub(st, ano, counter - 1);
}
fclose(file);
}
}
When i run this in main that has the following lines:
printf("Creating Stat Table");
StatTable st=newStatTable();\\This Line is correct, i checked it,i hope
printf("Creating index");
IndexOfAuts* ioa=newIndexOfAuts();
printf("Loading Modules");
loadModules(filename,ioa,st);
Those prints were for me to see where was the cause of the seg fault, but the last line printed was the "Creating Index".
There are several cases of undefined behavior and one memory leak (and a possible case of undefined behavior too):
You have this initialization ioa[i]->biggestn=""; It make the biggestn member point to a constant array of one character (the '\0' character). You then do strcpy(ioa[index]->biggestn,aux); which will write over a constant character, and then go outside of the array writing into unknown memory.
You have this: char* aux=malloc(sizeof(nome)); That allocates only 4 or 8 bytes, which the size of the pointer and not what the pointer points to. Use strlen to get the length of a string.
For the above allocation you also need to allocate a byte extra, as strlen only returns the length of the string without the terminator.
You have aux=trim(nome); This overwrites the pointer you just allocated, leading to a memory leak.
The above call might also lead to undefined behavior if you return a pointer to a local variable or array.
There are probably other problematic lines, these were just the ones I found on a quick glance.
And a general tip: Learn to use a debugger! The debugger is a programmers best tool next to the compiler. If you run your program in a debugger, the debugger will stop at the location of the crash, and let you examine (and also walk up) the function call stack, as well as let you examine values of variables.
After searching through many threads on similar issues, I've been unable to determine why I've been getting a seg fault with my program. I have two files: buffer.c where I create a circular buffer and deposit/remove values from it and a main file where several threads call the operations on the circular buffer with user input. Semaphores are used to prevent concurrent access.
Here are the relevant parts of my main program:
int main (int argc, char const *argv[]) {
st_init();
Buffer *bufferA,*bufferB,*bufferC;
createBuffer(bufferA,128);
createBuffer(bufferB,128);
createBuffer(bufferC,128);
// Create the struct used to initialize threads.
ThreadInit initA = {
bufferA,
bufferA
};
ThreadInit initB = {
bufferA,
bufferB
};
ThreadInit initC = {
bufferB,
bufferC
};
ThreadInit initD = {
bufferC,
bufferC
};
// Create threads
if (st_thread_create(getInputStream, &initA, 0, 0) == NULL) {
perror("Thread a creation failure.");
exit(EXIT_FAILURE);
}
if (st_thread_create(convertCR, &initB, 0, 0) == NULL) {
perror("Thread b creation failure.");
exit(EXIT_FAILURE);
}
if (st_thread_create(squashChar, &initC, 0, 0) == NULL) {
perror("Thread c creation failure.");
exit(EXIT_FAILURE);
}
if (st_thread_create(printOutput, &initD, 0, 0) == NULL) {
perror("Thread d creation failure.");
exit(EXIT_FAILURE);
}
// Exit from main via ST.
st_thread_exit(NULL);
return 0;
}
void *getInputStream(void *state) {
ThreadInit *threadInit = state;
char inputChar = getchar();
while (inputChar != EOF) {
deposit(inputChar, threadInit->produceBuff); //where segfault occurs
inputChar = getchar();
st_usleep(SLEEP_TIME);
}
st_thread_exit(NULL);
}
and buffer.c
void createBuffer(Buffer *buff, int buffSize){
buff = (Buffer*) calloc(1, sizeof(Buffer));
semaphore mutex,emptyBuffers,fullBuffers;
buff->mutex = calloc(1,sizeof(semaphore));
buff->emptyBuffers = calloc(1,sizeof(semaphore));
buff->fullBuffers = calloc(1,sizeof(semaphore));
createSem(buff->mutex,1);
createSem(buff->emptyBuffers,buffSize);
createSem(buff->fullBuffers,0);
buff->charBuff = malloc(sizeof(char) * buffSize);
buff->nextIn = 0;
buff->nextOut = 0;
buff->buffSize = buffSize;
}
The seg fault occurs the first time an operation is done on the semaphores in my buffers, which leads me to believe their memory is improperly allocated, though I included the code from my main in case I'm wrong in that assumption. Also, in case it's not clear from my code, I'm quite new to C, so I'd appreciate any guidance. Thanks!
Here is the error
void createBuffer(Buffer *buff, int buffSize){
buff = (Buffer*) calloc(1, sizeof(Buffer));
you need to return the pointer of the buffer otherwise you are not returning the changed pointer to the caller
void createBuffer(Buffer **buff, int buffSize){
*buff = calloc(1, sizeof(Buffer));
a bit simplified : it is similar to
int foo(int a)
{
a = 1; // 1 not visible outside foo
}
and
int foo(int *a)
{
*a = 1; // 1 is visible outside foo
}
also in C you don't cast what is returned from calloc/malloc only if you are compiling with a C++ compiler but then you should use new instead
In c, function parameter is passed by value so your createBuffer() function didn't really create anything; it just leaked memory instead.
One easy fix is to allocate the memory in main():
bufferA = (Buffer*) calloc(1, sizeof(Buffer));
and remove this line:
buff = (Buffer*) calloc(1, sizeof(Buffer));
I don't see how your createSem() is implemented by you may want to check it too.
While working on a program which requires frequent memory allocation I came across behaviour I cannot explain. I've implemented a work around but I am curious to why my previous implementation didn't work. Here's the situation:
Memory reallocation of a pointer works
This may not be best practice (and if so please let me knwow) but I recall that realloc can allocate new memory if the pointer passed in is NULL. Below is an example where I read file data into a temporary buffer, then allocate appropriate size for *data and memcopy content
I have a file structure like so
typedef struct _my_file {
int size;
char *data;
}
And the mem reallocation and copy code like so:
// cycle through decompressed file until end is reached
while ((read_size = gzread(fh, buf, sizeof(buf))) != 0 && read_size != -1) {
// allocate/reallocate memory to fit newly read buffer
if ((tmp_data = realloc(file->data, sizeof(char *)*(file->size+read_size))) == (char *)NULL) {
printf("Memory reallocation error for requested size %d.\n", file->size+read_size);
// if memory was previous allocated but realloc failed this time, free memory!
if (file->size > 0)
free(file->data);
return FH_REALLOC_ERROR;
}
// update pointer to potentially new address (man realloc)
file->data = tmp_data;
// copy data from temporary buffer
memcpy(file->data + file->size, buf, read_size);
// update total read file size
file->size += read_size;
}
Memory reallocation of pointer to pointer fails
However, here is where I'm confused. Using the same thought that reallocation of a NULL pointer will allocate new memory, I parse a string of arguments and for each argument I allocate a pointer to a pointer, then allocate a pointer that is pointed by that pointer to a pointer. Maybe code is easier to explain:
This is the structure:
typedef struct _arguments {
unsigned short int options; // options bitmap
char **regexes; // array of regexes
unsigned int nregexes; // number of regexes
char *logmatch; // log file match pattern
unsigned int limit; // log match limit
char *argv0; // executable name
} arguments;
And the memory allocation code:
int i = 0;
int len;
char **tmp;
while (strcmp(argv[i+regindex], "-logs") != 0) {
len = strlen(argv[i+regindex]);
if((tmp = realloc(args->regexes, sizeof(char **)*(i+1))) == (char **)NULL) {
printf("Cannot allocate memory for regex patterns array.\n");
return -1;
}
args->regexes = tmp;
tmp = NULL;
if((args->regexes[i] = (char *)malloc(sizeof(char *)*(len+1))) == (char *)NULL) {
printf("Cannot allocate memory for regex pattern.\n");
return -1;
}
strcpy(args->regexes[i], argv[i+regindex]);
i++;
}
When I compile and run this I get a run time error "realloc: invalid pointer "
I must be missing something obvious but after not accomplishing much trying to debug and searching for solutions online for 5 hours now, I just ran two loops, one counts the numbers of arguments and mallocs enough space for it, and the second loop allocates space for the arguments and strcpys it.
Any explanation to this behaviour is much appreciated! I really am curious to know why.
First fragment:
// cycle through decompressed file until end is reached
while (1) {
char **tmp_data;
read_size = gzread(fh, buf, sizeof buf);
if (read_size <= 0) break;
// allocate/reallocate memory to fit newly read buffer
tmp_data = realloc(file->data, (file->size+read_size) * sizeof *tmp_data );
if ( !tmp_data ) {
printf("Memory reallocation error for requested size %d.\n"
, file->size+read_size);
if (file->data) {
free(file->data)
file->data = NULL;
file->size = 0;
}
return FH_REALLOC_ERROR;
}
file->data = tmp_data;
// copy data from temporary buffer
memcpy(file->data + file->size, buf, read_size);
// update total read file size
file->size += read_size;
}
Second fragment:
unsigned i; // BTW this variable is already present as args->nregexes;
for(i =0; strcmp(argv[i+regindex], "-logs"); i++) {
char **tmp;
tmp = realloc(args->regexes, (i+1) * sizeof *tmp );
if (!tmp) {
printf("Cannot allocate memory for regex patterns array.\n");
return -1;
}
args->regexes = tmp;
args->regexes[i] = strdup( argv[i+regindex] );
if ( !args->regexes[i] ) {
printf("Cannot allocate memory for regex pattern.\n");
return -1;
}
...
return 0;
}
A few notes:
the syntax ptr = malloc ( CNT * sizeof *ptr); is more robust than the sizeof(type) variant.
strdup() does exactly the same as your malloc+strcpy()
the for(;;) loop is less error prone than a while() loop with a loose i++; at the end of the loop body. (it also makes clear that the loopcondition is never checked)
to me if ( !ptr ) {} is easyer to read than if (ptr != NULL) {}
the casts are not needed and sometimes unwanted.
I'm trying to implement a circular buffer for use as a frame buffer with OpenCV (using C).
I've shamelessly stolen the circular buffer implementation from this post to save reinventing the wheel:
EDIT: OK, so I've redefined a few things. Namely I implemented my own circular buffer. Now I'm getting errors which don't make sense.
Here is the circular buffer implementation I'm using:
#define BUFFER_SIZE 100
typedef struct
{
IplImage* queue[BUFFER_SIZE];
IplImage *in;
IplImage *out;
int num_frames;
int in_ctr;
int out_ctr;
int update_flag;
} frame_buffer;
Here is the get function:
IplImage* buff_get()
{
IplImage* nextfr;
if(frbuff.num_frames == 0)
{
return NULL;
}
nextfr = frbuff.out++;
if(++frbuff.out_ctr == BUFFER_SIZE)
{
frbuff.out = &frbuff.queue[0];
frbuff.out_ctr = 0;
}
--frbuff.num_frames;
return nextfr;
}
Here is the put function:
int buff_put(IplImage* nextfr)
{
if(++frbuff.num_frames > BUFFER_SIZE)
{
return 0;
}
frbuff.in++;
frbuff.in = nextfr;
if(++frbuff.in_ctr == BUFFER_SIZE)
{
frbuff.in = &frbuff.queue[0];
frbuff.in_ctr = 0;
}
return 1;
}
Everything seems to go OK. Frames appear on the buffer, which I know because I can print the size out. But it all goes bad when I try to show the image that's on the buffer.
If I then try to do this:
IplImage* curr_frame = cvCreateImage(cvSize(640,480),8,3);
cvNamedWindow("proc_window",CV_WINDOW_AUTOSIZE);
cvShowImage("proc_window",curr_frame);
while(1)
{
if(buff_size() > 0)
{
if(buff_flag_check()) curr_frame = buff_get();
if(curr_frame != NULL)
{
cvShowImage("proc_window",curr_frame);
}
}
I recieve the following error upon calling cvShowImage():
OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /home/fagg/src/OpenCV-2.3.1/modules/core/src/array.cpp, line 2482
terminate called after throwing an instance of 'cv::Exception'
what(): /home/fagg/src/OpenCV-2.3.1/modules/core/src/array.cpp:2482: error: (-206) Unrecognized or unsupported array type in function cvGetMat
I'm quite confused as to what's going on here. Hopefully someone with fresher eyes than myself can see what's going on...
The snippet of code you provided won't compile as cb_init() takes a pointer to a circular_buffer as first argument.
and if you get a segfault in cb_init() it is because malloc() fails to return the requested size and the implementation in the link does not handle errors.
void cb_init(circular_buffer *cb, size_t capacity, size_t sz)
{
cb->buffer = malloc(capacity * sz);
if(cb->buffer == NULL)
// handle error
cb->buffer_end = (char *)cb->buffer + capacity * sz;//segfault when using cb->buffer which is null in case of malloc() failure
cb->capacity = capacity;
cb->count = 0;
cb->sz = sz;
cb->head = cb->buffer;
cb->tail = cb->buffer;
}