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.
Related
The user specifies the number of lines in the output in the arguments (as the size of the page in pagination), by pressing the key he gets the next lines. How it works now:
Let's say the user chose to receive 1 row at a time:
first string
first string
second string
first string
second string
third string
struct result {
char part[32768];
int is_end_of_file;
};
struct result readLines(int count) {
int lines_readed = 0;
struct result r;
if (count == 0) {
count = -1;
}
while (count != lines_readed) {
while (1) {
char sym[1];
sym[0] = (char) fgetc(file);
if (feof(file)) {
r.is_end_of_file = 1;
return r;
}
strcat(r.part, sym);
if (*"\n" == sym[0]) {
break;
}
}
lines_readed++;
}
return r;
}
int main(int argc, char *argv[]) {
file = fopen(argv[1], "r");
while (1) {
struct result res = readLines(atoi(argv[2]));
printf("%s", res.part);
if (res.is_end_of_file) {
printf("\nEnd of file!\n");
break;
}
getc(stdin);
}
closeFile();
return 0;
}
I know that when I define a struct in the readLines function, it is already filled with previous data. Forgive me if this is a dumb question, I'm a complete newbie to C.
I'm not sure what is the question here, however I'll do my best to address what I understand. I assume the problem lies somewhere around the "previous data" you mentioned in the title and in the comments to the question.
Let's first set an example program:
#include <stdio.h>
struct result {
char part[10];
};
int main (int argc, char *argv[]) {
struct result r;
printf(r.part);
return 0;
}
The variable r has a block scope, so it has automatic storage duration. Since it has automatic storage duration, and no initializer is provided, it is initialized to an indeterminate value (as mentioned by UnholySheep and n. 1.8e9-where's-my-share m. in the comments to the question). I don't yet get all the C intricacies, but based on this, I guess you cannot rely on what the value of r will be.
Now, in the comments to the question you try to understand how is it possible that you can access some data that was not written by the current invokation of your program. I cannot tell you exactly how is that possible, but I suspect it is rather platform-specific than C-specific. Maybe the following will help you:
What is Indeterminate value?
What happens to memory after free()?
Why memory isn't zero out from malloc?
Going further, in the line
printf(r.part);
first we try to access a member part of r, and then we call printf with the value of this member. Accessing a variable of an indeterminate value results in undefined behavior, according to this. So, in general, you cannot rely also on anything that happens after invoking r.part (it doesn't mean there is no way of knowing what will happen).
There is also another problem with this code. printf's first parameter is interpreted as having the type const char *, according to man 3 printf, but there is provided a variable that has the type struct result. Indeed, there is produced the following warning when the code is compiled with gcc with the option -Wformat-security:
warning: format not a string literal and no format arguments [-Wformat-security]
Unfortunately, I don't know C well enough to tell you what precisely is happening when you do such type mismatch in a function call. But as we know that there already happened undefined behavior in the code, this seems less important.
As a side note, a correct invokation of printf could be in this case:
printf("%p", (void *)r.part);
r.part is a pointer, therefore I use the %p conversion specifier, and cast the value to (void *).
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 3 years ago.
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.
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.
Improve this question
i got this warning " assignment makes pointer from integer without a cast "
(MARKED IN CODE PIECE) the code works fine, what i'm doing wrong and how can i fix this warning? thanx
void Read_Keys(char *keys[MAX_LEN]) //Read the keys from input file
{
char c,Fname[MAX_LEN];
gets(Fname);
FILE *fptr = (fopen(Fname, "r")); // Input stream pointer assume
if(fptr == NULL)
{
printf("No Such File...");
exit(EXIT_FAILURE);
}
if(fptr) //if not empty get in
{
int i = 0;
while((c = getc(fptr)) != EOF) //while loop copies each char from file
{ //to keys array
** keys[i] = c; // ** WARNING IS HERE
i++;
}
keys[i+1] = END; //ending point assume
}
fclose(fptr); //Close file for security issues
} ```
The parameter keys is declared like
char *keys[MAX_LEN]
the compiler adjusts it to the following declaration
char **keys
So in this statement
keys[i] = c;
the left operand has the type char * that is it is a pointer while the right operand has the type char.
So the compiler issues a warning because this assignment does not make sense.
I suspect that in any case the parameter is declared incorrectly. It seems you mean the following declaration
void Read_Keys(char ( *keys )[MAX_LEN]);
that is you are trying to pass a two dimensional array to the function. But in any case this code snippet
int i = 0;
while((c = getc(fptr)) != EOF) //while loop copies each char from file
{ //to keys array
keys[i] = c; // ** WARNING IS HERE
i++;
}
keys[i+1] = END; //ending point assume
}
is invalid because it trues to write all the file in one record instead of an array of records.
You keys parameter is an array of MAX_LEN pointers to char. So, if you want to assign a value inside this array, it should be a pointer to a character type. Here, getc() returns a character, not a pointer.
I think what you expect is void Read_Keys(char *keys), with the following calling code:
char keys[MAX_LEN];
Read_Keys(keys);
Thus, your keys array is decayed into a char * pointer when Read_Keys is called. Inside Read_Keys, you can access all your array elements using an index, like keys[2].
Obviously, you also need to pass you array length to Read_Keys, so the function knows which array index is valid and which one is not.
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
[EDIT] The main problem was that the fitness of my evolution returned the same value every time after changing some int into float values. The misterious point is that i restarted the computer and it surprisingly worked again.
I'm calling a function from my main, when i debug the code, the variables contain data, but in the header of the function, when i debug, my data is lost and the reference on memory is the same (i'm compiling with visual Studio 2013), this only happens in some of the variables (you can check which ones in the pictures below)
int main(){
float resultados[NUMCROMOSOMAS][CANTIDADMEDICIONES];
int in[CANTIDADMEDICIONES][NUMVAR];
char gramaticas[NUMCROMOSOMAS][LONGITUDCADENA];
int mejorValorIndividuo[100];
char variableNames[NUMVAR + 1];
float fitness[NUMCROMOSOMAS];
char mejorindividuo[LONGITUDCADENA];
float medicionesObtenidas[NUMCROMOSOMAS][CANTIDADMEDICIONES];
int i,j;
(Initializations, some of the relevant ones are)
for (i = 0; i < NUMCROMOSOMAS; i++)
fitness[i] = 0.0;
for (i = 0; i < CANTIDADMEDICIONES; i++)
in[i][0] = i;
Yeah, that was a bidimensional array using one column
And here is the main loop of my program
int curr = MAXINT;
i = 0;
while ( isNotGoodEnough(curr) ){
i++;
curr = generacion(poblacion, results, input, collectedData, gramaticas, mejorindividuo, variableNames, fitness);
}
return poblacion[0][0];
}
The header of my function is this:
int generacion(int poblacion[NUMCROMOSOMAS][SIZECROMOSOMAS],
float resultados[NUMCROMOSOMAS][CANTIDADMEDICIONES],
int in[CANTIDADMEDICIONES][NUMVAR],
float valoresEsperados[NUMCROMOSOMAS][CANTIDADMEDICIONES],
char gramaticas[NUMCROMOSOMAS][LONGITUDCADENA],
char * mejorIndividuo,
char variableNames[NUMVAR],
float fitness[NUMCROMOSOMAS]){
Here is the compiler before the calling
Here is the compiler right after the calling
What i'm doing wrong?
When you have an argument declaration like
int in[CANTIDADMEDICIONES][NUMVAR]
that's not really what the compiler uses, what it translates it to is
int (*in)[NUMVAR]
In other words in is a pointer and not an array.
What you're seeing in the debugger in the function is the pointer, but since the size of the data pointed to by the pointer is unknown the debugger can't show you the data directly. If you explicitly, in the debugger when in the function, check in[0] you will see that the data is correct.
In other words, it's not a problem with the code, it's how the debugger displays (or rather doesn't display) the data.
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
I have a struct array that has the format:
struct command functions[] = {
{"1", function1},
{"2", function2},
etc....
}
In a function run(char* function), I check if the parameter is equivalent to one of the strings stored in the struct array. If it is, I want to call the corresponding function. For example, if "1" is passed in, I call function1().
How would this be accomplished?
So far, I have
run(char* function) {
for (int i = 0; i < num_functions; i++) {
if(*function == functions[i]) {
return (*function)();
}
}
}
With the following errors:
error: invalid operands to binary == (have int and struct command)
error: called object *function is not a function
There are several issues with your code that seem to be causing an error, but unfortunately you haven't posted enough for me to completely fix them.
In the line if(*function == function[i]) you are using function[i] when you probably want to be using functions[i] (with an "s")
In the same line, you are comparing a char against a struct command. You probably want to access the member of the struct that contains the string shown in your first code snippet.
You are (presumably) comparing a single character against a string. You should do this using strcmp.
You are not calling the function, you're calling a char, which just won't work.
At a guess, I think you want something like this:
run(char* function_name) {
for (int i = 0; i < num_functions; i++) {
struct_command function = functions[i];
if(strcmp(function_name, function.name) == 0) {
return function.exec();
}
}
}
This assumes that the members in your struct command are named name and exec.
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