Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I am trying to sort an array of names via qsort.
This is my code
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int myCompare (const void * a, const void * b ) {
return *(char*)a - *(char*)b;
}
int main(void) {
int i;
char fileArr[] = {"inputbv", "inputa","inputzef",};
int stringLen = sizeof(fileArr) / sizeof(char *);
qsort(fileArr, stringLen, sizeof(char *), myCompare);
for (i=0; i<stringLen; ++i)
printf("%d: %s\n", i, fileArr[i]);
}
This code doesn't print anything at the end. It just ends so it seems like it deletes the entries in the char array
First off, you're missing a *:
char *fileArr[] = {"inputbv", "inputa","inputzef",};
This doesn't explain why you're not sorting correctly, which is a different issue, but it does explain why you're getting no output. (A validating compiler, like gcc -Wall, would have told you that that declaration is invalid without that missing star.)
There are a number of other issues here, though. First off, as one of the commenters alluded to, the myCompare() function is declared with the right type, but it doesn't quite do what you think it does:
int myCompare(const void *a, const void *b)
{
...
}
That's because qsort() passes the address to each chunk of data, not the chunk of data itself. The chunks of data in this case are pointers to character arrays, so qsort() is going to pass pointers to pointers to your comparison function. Those aren't single stars there; they're actually two stars in disguise.
Secondly, comparing pointers does you no good: The pointers are, almost by definition, random values. Your comparison function, as written, even if you corrected it for the number of *'s that are supposed to be there, would still be wrong:
/* Don't do this. */
return *(char **)a - *(char **)b;
That's literally more-or-less "sort by the random locations of these strings in memory," which doesn't help you at all for putting them in order.
The right thing to do is not to add yet another star (writing **(char **)a - **(char **)b literally means "compare the first characters against each other"). The right thing to do is invoke strcmp() to compare the two strings lexically:
int myCompare(const void *a, const void *b)
{
return strcmp(*(char **)a, *(char **)b);
}
That's what you should be using.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Stack create(int c)
{
Stack S=(Stack)malloc(sizeof(struct stack));
S->size=c;
S->top=-1;
S->array=(char *)malloc(sizeof(char)*c);
return S;
}
Stack makeEmpty(void)
{
Stack *S1=create(100);
S1[0]->top=-1;
return S1;
}
char pop(Stack S)
{
return S->array[S->top--];
};
int main(void)
{
Stack *S1;
S1=makeEmpty();
int j;
int k=0;
char result[30];
for(j=0; j<2; j++)
{
char result1=pop(S1);
strcat(result, result1);
k++;
}
}
I skipped some parts, like typedef struct stack Stack;
What I wanted to do was pop out elements from the stack while for-loop works. Then, store those elements in a new array which is result. To check whether it works or not, I printed out but I had a runtime error. How to store the element and how to print it out?
I've made copy&paste of your code, and it doesn't get compiled. I think that
you are either not posting your actually code nor you don't bother to compile and read the compiler warnings. It's rather difficult to help you. Here some things I noticed:
1.
create must return a pointer to Stack, not the object.
Stack *create(int c)
{
Stack *S = malloc(sizeof *S);
S->size=c;
S->top=-1;
S->array = malloc(c);
return S;
}
2.
Same goes for makeEmpty
Stack *makeEmpty(void)
{
Stack *S1=create(100);
S1->top=-1;
return S1;
}
3.
pop should get a pointer to Stack, not the object
char pop(Stack *S)
{
return S->array[S->top--];
};
Here you should check whether there are elements on your stack. int pop(Stack *S, char *val) where it returns 1 and writes on *val on
success, and returns 0 otherwise would be better.
4.
Judging from your pop you are pushing char only. I don't get what you
are trying to do with strcat. Either way, you are doing strcat wrong. You
are declaring a stack with 100 spaces, but you are only declaring 30 spaces
for result. What if you have more than 31 elements on your stack? I know
that you are only inspecting 2 elements but it's easy to overlook that and
expand it to go through all the stack without changing the memory requirements
for result.
Also strcat is a function that works with C-Strings, that means it expects
C-Strings. A C-String must be \0 terminated, yours are not. You have
something that looks like a C-String but it's not. If you insist on using
strcat, the you should do it like this:
for(j=0; j<2; j++)
{
char result1[] = { pop(S1), 0 };
strcat(result, result1);
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
+I'm trying to pass from the main an array of CustomStruct by reference, but im doing something wrong:
I think i'm asking correctly for memory, but it doesn't seem so, because when i try to force some values, i get core dumped and i absolutely don't know why.
void readFile(OwnStruct **restaurant){
FILE *f;
int numTaules = 0;
f = fopen("hello.txt", "r");
if(f == NULL){
printf("Error at opening!\n");
exit(0);
}
fscanf(f,"%d",&numTaules);
//Asking for memory
*restaurant = (OwnStruct*)malloc(sizeof(OwnStruct) * numTaules);
//From here, at some point: Core Dumped
restaurant[0]->ocupades = 1;
restaurant[0]->disponibles = 2;
restaurant[1]->ocupades = 3;
restaurant[1]->disponibles = 4;
printf("%d\n",restaurant[0]->ocupades);
printf("%d\n",restaurant[0]->disponibles);
printf("%d\n",restaurant[1]->ocupades);
printf("%d\n",restaurant[1]->disponibles);
}
int main(){
typedef struct(){
int ocupades;
int disponibles;
}
OwnStruct *restaurant;
readFile(&restaurant);
return 0;
}
You are referencing the array wrong:
So far so good:
*restaurant = (OwnStruct*)malloc(sizeof(OwnStruct) * numTaules);
This is wrong:
restaurant[0]->ocupades = 1;
It should be:
(*restaurant)[0].ocupades = 1;
You must dereference the pointer to your pointer. That expression then points to the first element of the allocated array. The parentheses are needed, because postfix operators like EXPR[0] take precedence over unary operators like *EXPR, so *EXPR[0] is treated as *(EXPR[0]).
Suggestion: Work with a local pointer which is just Ownstruct *ptr. Then, just before returning from the function, store that pointer:
*restaurant = ptr;
Then you can just have ptr[0]->field = value type code in your function.
Your problem is that your function
void readFile(char fileName[], OwnStruct **restaurant)
expects two parameter, but you pass just one.
readFile(&restaurant);
Just write
readFile("myFile.txt", &restaurant);
or define your function as
void readFile(OwnStruct **restaurant)
The example you give should not currently compile - readFile expects a filename and a pointer to a pointer of OwnStruct. Your main is just providing the pointer.
The struct should defined somewhere at the top (before its use in main and readFile)
readFile is also reading numTauls from a file but then assuming it is at least 2 when assigning values to the allocated memory.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
How do I dynamically create an array of struct in a function in C?
The struct:
typedef struct Track {
char artist[LONGSTR];
char file[LONGSTR];
int id;
int isAlbum;
char name[LONGSTR];
int pos;
char title[LONGSTR];
int time;
} Track;
The function:
int
processplaylist (struct Track** tracks, char* resp)
{
//count the tracks to return
//allocate space for the resulting tracks
*tracks = mem_alloc (count * sizeof (struct Track));
//process each track
return count;
}
And the usage:
char playliststr[] = "file: some-mp3\nTitle: Dire Straits - Romeo And Juliet\nName: TheRadio\nPos: 0\nId: 12\nOK\n"
struct Track* tracks = NULL;
int count = mpd_processplaylist(&tracks, playliststr);
Within the function the tracks are nicely processed and upto the return statement tracks points to the right location to get to the tracks. Most questions I have seen are about arrays to values, not structs.
This answer returns an array of structs, but I would like to return the count (question of style) and return the array through the parameter.
What is going wrong? After the function returns, count has the right value and tracks is still NULL.
As the not so nice people pointed out by down voting the question, the question is too broad and vague. I apologize for that, I was desperate.
As the nice people in the comments confirmed, the code is correct. Even though the debugger showed that just before the return statement everything was OK and after returning to the usage it was not.
By commenting out code lines and logging a lot, there are two things to note.
Within the function, you must refer to the individual tracks as (*tracks + i) or, for example, (*(*tracks + i)).file. Indeed, not shown in the sample code. I had tried *(tracks + i), &tracks[i] and tracks + i, which in the debugger all seemed to work and did not cause immediate errors. I guess the code messed up memory that only came out after the return.
Outside the function, in the usage, you refer to the tracks as an array, as tracks[i] or, for example, tracks[i].file.
I hope that at least my answer helps.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I try to pass a two dimensional array as a parameter to a function like this:
void comb(int n, int array[n][n-1])
{
.....
}
And in the main function:
int main(int argc, const char * argv[])
{
const int p = 10;
int array[p][p-1];
comb(p, array); //Error:No matching function for call to 'comb'
return 0;
}
The "comb" function is declared above the main function. But Xcode gives me the error message on line "comb(p, array)" that "No matching function for call to 'comb' ".
I don't know how I could fix this. Also, is there some better way to pass a 2-dim array as parameter?
Your code is correct in C99.
If you get a compiler error, it could be because you are not showing the real code, or you are not invoking your compiler in C99 mode.
In C11 it is optional whether the compiler supports VLA, but your compiler documentation should indicate whether or not it is supported.
There is no other way to pass a VLA as parameter.
If your array dimension is known at compile-time then you can replace const int p = 10; with #define ARRAY_DIM 10 ; then your array will no longer be a VLA and the function can simply be:
void comb(int array[ARRAY_DIM][ARRAY_DIM-1])
{
Never passed a matrix, but when you pass arrays, the name is just the pointer to the first element.
char myArray[10];
where myArray is really a char pointer rather than a char.
You need to change something. Passing big things in functions is asking for a pointer
If comb take an array
void comb(int n, int array[n])
this should be put like
void comb(int n, int*array)
And then access to elements are in the fashion
*(array+k) ... // equals to array[k]
YOU CANNOT DO THIS
array[k] ... // Erro.
And call comb in main just in the way you did, since array names are already pointers
Not sure for bidimentional but almost sure the same, since bidim are just a big unidimensional array arranged in another way.
When passing pointer, function forget about boundaries.
Good practice is to help the function avoid disasters passing the max len
void comb(int n, int*array,int len)
{
int k=0;
While(*(array+k) !=n) // Search array for a number equal to "n".....
{
k++;
if(k>len)
return 0; // Avoid seeking outside the array, cut now. nice plase to return 0 (not found)
}
return 1; // got a hit before reaching the end.
}
Meanwhile in the main call:
comb(p, array, sizeof(array)/sizeof(array[0]); // third param is the number of elements
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
Here is the whole code I have so far for the assignment I am having trouble with:
// This program takes a quadratic from the user, and prints the solution(s) if they exist.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
// Define quadratic structure
typedef struct quadratic{
float a, b, c;
float discriminant;
float real_root_1;
float real_root_2;
float complex_root;
} Quadratic;
// 'Redefine' malloc to also check allocation of memory when called, as suggested
void xmalloc(size_t n){
void *p = malloc(n);
if (p == NULL) {
printf("\n ERROR: Unable to allocate memory! \n");
exit(1);
}
return p;
}
// Following example code in lecture notes
Quadratic *newquadratic() {
Quadratic *q = xmalloc(sizeof *q);
return q;
}
int main () {
return 0;
}
Now I'm not too sure what I'm doing, but I'll ask about that after the problem this code has first. On the "Quadratic *q = xmalloc()" line I get the error "Void value not ignored as it ought to be", however this code was basically copied out the lecture notes and the variables names changed! (as we were suggested to do..). I tried removing the void tags in xmalloc, which then started complaining of undefined variables, so I'm really not sure what's going on.
More generally, I'm confused as hell about some parts of this: Namely, the function "Quadratic *newquadratic()". Why the hell is there a star there!? How can a pointer be a function..? Not only that, but it would seem if I remove the star, everything is ok only if I star the return, "return *p;". It would seem that this function can only return pointers, but I defined Quadratic as a variable type (structure), so.. why would it want to return a pointer rather than a 'quadratic'?
As things currently stand you xmalloc() function is useless. It allocates memory but does not return anything so no-one can use the allocated memory.
Possibly you made a transcription error:
void * xmalloc(size_t n){
void *p = malloc(n);
if (p == NULL) {
printf("\n ERROR: Unable to allocate memory! \n");
exit(1);
}
return p;
}
If you have xmalloc declared as returning a void* you can then return something and use it in the calling function.
The implication to me is that you don't understand the difference between a void and a void*. A function returning a void is returning nothing, there is no value to use. A void* on the other hand is a pointer to anything, and hence is a great representation of a generally useful block of memery allocated by malloc.
xmalloc should return a pointer if you're using it like malloc.
Then you use it so allocate N bytes of memory for a Quadratic structure.