Note that there are some explanatory texts on larger screens.

plurals
  1. POCasting the void pointer and printing with format specifiers
    primarykey
    data
    text
    <p>Okay this is for a school project but my question has <strong>nothing to do with anything regarding a specific implementation</strong>, nor am I asking for any help regarding the project itself. I am only giving this warning because I want to give context for what I am doing, but this is rather a general question regarding the casting of void pointers, framed within the context of a project... This function I'm writing isn't even FOR the project, it's just something I wrote as a testing mechanism to see if my generation of a data structure is working... and it lead me to a problem involving printf(), format specifiers, and casting.... I basically have to implement a linked-list (called a 'queue' but is not really a queue at all), and I wrote a function to test it.</p> <p>There is basically a struct called a "Chunk" with some variables (<strong>first</strong> is the index within the larger array that is the first element of a given "Chunk", and <strong>arr</strong> is basically larger_array[c->first], but it's actually a void pointer as such: <strong>void *arr</strong> where c is a pointer to a Chunk) that indicate a position in a larger array. So basically if you have an array like a = {5,7,3,4,6,9,1,2}, and you were given a chunk size of two, you have 4 chunks each of whom have an "arr" void pointer variable which point respectively to 5, then 3, then 6, then 1. </p> <p>Anyways, I wrote a "print_queue" function (actually a linked-list of Chunks) and yay! It prints all the information as desired, and here is the core part that I will share:</p> <pre><code> while (index &lt; num_chunks) { first = c-&gt;first; printf("Chunk %d: first is %d and a[%d] is ", index, first, first); if (elem_size == LONG_SIZE) /* LONG_SIZE defined above as 8 */ printf("%ld\n", c-&gt;arr); else if (elem_size == INT_SIZE) /* INT_SIZE defined above as 4 */ printf("%d\n", c-&gt;arr); else if (elem_size == CHAR_SIZE) /* CHAR_SIZE defined above as 1 */ printf("%c\n", c-&gt;arr); index++; if (c-&gt;next != NULL) c = c-&gt;next; } </code></pre> <p>I basically wanted to write a function that would be able to print my linked-list for any of the three types (longs, ints, and chars) for testing purposes while I implement the actual functionality of the project (multithreaded merge-sort). So the code above actually works! This is the output for this array input: </p> <pre><code> char original[] = {'z', 'y', 'x', 'w', 'v', 'u', 't', 's'}; </code></pre> <p>Output:</p> <pre><code> Chunk 0: first is 0 and a[0] is z Chunk 1: first is 2 and a[2] is x Chunk 2: first is 4 and a[4] is v Chunk 3: first is 6 and a[6] is t </code></pre> <p>So it works! Yay! However, I get these compiler warnings:</p> <pre><code>mergesort.c: In function 'print_chunk_queue': mergesort.c:85:7: warning: format '%ld' expects argument of type 'long int', but argument 2 has type 'void *' [-Wformat] mergesort.c:87:7: warning: format '%d' expects argument of type 'int', but argument 2 has type 'void *' [-Wformat] mergesort.c:89:7: warning: format '%c' expects argument of type 'int', but argument 2 has type 'void *' [-Wformat] </code></pre> <p>So what I did was cast all the c->arr 's to (type *) c->arr, but that gave me more warnings about "oh we want an int but you have us an int pointer" so what I did was then:</p> <pre><code> * ((type *) c-&gt;arr) </code></pre> <p>Basically dereferencing my casted void pointer (which is NEVER null! It always is pointing to valid numbers, at least with the input I provided it!), and then that gives me a segmentation fault!. So I'm pretty frustrated because I went from working output with a ton of "warnings" to useless segmentation faults. </p> <p>EDIT:</p> <p>definition of the data structure, as requested:</p> <pre><code>typedef struct chunk { void *arr; struct chunk *next; int first; } Chunk; </code></pre> <p>this is how I am setting the state of a single chunk and creating a linked-list of chunks:</p> <pre><code> while (index &lt; number_of_chunks) { if (index == 0) { if ((current = malloc(sizeof(Chunk))) == NULL) err(EX_OSERR, "memory allocation has failed\n"); head = current; } current-&gt;first = (chunk_size * index); current-&gt;arr = ((char *) array)[current-&gt;first]; current-&gt;size = chunk_size; if (index != (number_of_chunks - 1)) { if ((current-&gt;next = malloc(sizeof(Chunk))) == NULL) err(EX_OSERR, "memory allocation has failed\n"); current = current-&gt;next; } else { tail = current; } index += 1; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload