Passing parameters by refection - with pointers, using * - is not magic!
it is necessary to understand what she does -
In C we indicate that a function receives a pointer, with "*", practically only to make the program easier to read - depending on the configurations the compiler can give a Warning or an error if we use it incorrectly - and depending on how wrong we use it, the compiler has nothing to do - nor can he warn you. That’s the case there.
So keep in mind that a pointer is a number. It indicates a position in the process memory. Let’s assume that its leDados
is called with the vector dado
at memory position "1000".
When you change something in the content of that pointer - you want to change any existing [i] value, it will work - and that’s how the reference call is used.
However, you try to make a change to the pointer address itself!
When you write dado = realloc(dado, tamanho);
the value 1000
data may remain the same, but only if the realloc
achieve greater memory space in the same block - but it can return another value - if you cannot increase the space allocated at address 1000 to the requested size, the call can transfer your data to another address (for example, 2000) - and returns "2000" which is in the local variable dado
. References within the same function to vector elements will continue to function - because they will be based on the new address "2000" - but the function that called leDados
only knows the address 1000
- (and leDados
there’s no changing that). When returning from the function leDados, hi program will try to read numbers in a position that is no longer allocated to the program data, and will give error.
The operation is intermittent, because if the realloc
always be able to expand the memory block at the initial address (1000 in our example), who calls leDados
continues with a valid reference to the vector. But if the realloc
had on some call that move the data block, the program gets lost. And the factors for this call having to change the position are numerous - having to do with the internal functioning of the system, and specific settings for the process profile. Anyway, even when this program works the way it is, it’s just by chance.
The simplest way to solve, since this function fills the whole vector, is to allocate the initial vector to itself, and it returns the new pointer.
Use a default value, such as a sentinel value, for the rest of the program to know the vector size:
#define SENTINELA = 0x8fffffff
DADOS *leDados(){
DADOS *dado;
int i = 0;
while (...){ ...; i++}
dado[i] = SENTINELA
return dado;
}
Another way is to pass the address where the "given" address is - so that the "leDados" function can change the memory address itself so that it is also changed in the calling function:
void main() {
DADOS * dado;
leDados (&dado);
}
...
int leDados( DADOS **dado){
...
while(fscanf(arq, "%d", &((*dado)[i].id)) != EOF){
*dado = realloc(*dado, tamanho);
...
}
...
return i;
}
And last but not least:
Unless you’re doing exercises to learn better C, and wanting to improve your understanding of pointers - that is - if you’re facing a real computing problem that you want to solve with this program on a personal computer it’s time to learn another language and not do this program in C. (Another use case for real C programs is if you are programming to run on a minicomputer, or microcontroller, such as Rduíno, or another Iot application)
In C you have to worry about everything: including allocating this data structure, and all the details of how you will manipulate it. In higher-level languages like Ruby, Python, PHP, Javascript, there are ready-to-use databanks, with all the part of Mea allocation, Elemtnos search, etc... ready to use.
For example, to read this same file in a Python program, putting all the numbers in a structure that the language would already prohibit memory, already knows the size, allows sorting, deletion, etc, you need to do:
dado = [int(n) for n in open(dados/config.txt").read().split()]
And then you just worry about using your numbers.
The troublemakers are 64bits or vice versa?
– Andre Mesquita
All windows I tested are 64 bits.
– DJM_JM
The problem appears to be a problem of Behavior Indefinite: tatnto can function as the programmer expects otherwise. Anyway it takes more information to be able to answer.
– pmg
What other information could be useful? Have you no idea what could be causing this instability? One question I have: O . exe generated externally is not the same used by the IDE to run the program?
– DJM_JM
"What other information could be useful?" -- The code! the loops, the input readings, the data structures, ...
– pmg
I put there the function that allocates the vector dynamically. I believe the error is there, because it is at this point that the program fails.
– DJM_JM