F
First, the keyword volatile it is used in the context of threads, so if you do not use them, it will not be necessary.Later, you assign a memory address of a variable still undeclared to another variable, so you only need to change the order of the instructions.Finally, you return a pointer, which is totally legal, but that pointer points to a variable that is local and that at the end of the call to the function that variable will be destroyed.The usual would be to create the vector in dynamic memory, but since it is not what you are looking for, the other solution is not to return a pointer to the vector, but the vector itself.But another problem will happen: when you return a data of a primitive type (or structures), what you return is a copy of the data that will be destroyed at the end of the function, while if you return a vector, which in essence is the same as returning a memory address (or pointer), that copy is not made.The solution to this is to wrap the vector in a structure, that when returning it will be copied before being destroyed in the stack.However, the code would remain:struct velocidades
{
uint8_t array_datos[3];
};
struct velocidades velocidad(uint16_t velocidad_0_to_1023, uint8_t direccion)
{
struct velocidades envoltura_velocidad;
if (velocidad_0_to_1023 > 1023) velocidad_0_to_1023 = 1023;
uint8_t velocidad_L = (uint8_t) 0x00FF & velocidad_0_to_1023;
uint8_t velocidad_H = (uint8_t) ((0x00FF & (velocidad_0_to_1023 >> 8)) | direccion);
envoltura_velocidad.array_datos[0] = 0x20;
envoltura_velocidad.array_datos[1] = velocidad_L;
envoltura_velocidad.array_datos[2] = velocidad_H;
return envoltura_velocidad;
}
Sources: https://stackoverflow.com/questions/19042552/returning-a-pointer-of-a-local-variable-c https://stackoverflow.com/questions/4570366/how-to-access-a-local-variable-from-a-different-function-using-pointers/4581061#4581061 EditionAs questions about the use of dynamic memory, I put the code, which makes use of the function malloc to book memory lot (or heap), although it wasn't what you were looking for at first.uint8_t * velocidad(uint16_t velocidad_0_to_1023, uint8_t direccion)
{
uint8_t * velocidades = (uint8_t *) malloc(3);
if (velocidad_0_to_1023 > 1023) velocidad_0_to_1023 = 1023;
uint8_t velocidad_L = (uint8_t) 0x00FF & velocidad_0_to_1023;
uint8_t velocidad_H = (uint8_t) ((0x00FF & (velocidad_0_to_1023 >> 8)) | direccion);
velocidades[0] = 0x20;
velocidades[1] = velocidad_L;
velocidades[2] = velocidad_H;
return velocidades;
}
You must bear in mind that the returned data will never be destroyed during the execution of the program, because as explicitly reserved, it must be explicitly released when you no longer need to use the vector.int main(int argc, char * argv[]) {
uint16_t velocidad_0_to_1023;
uint8_t direccion;
// Obtenemos los datos que vamos a pasar a la función
uint8_t * velocidades = velocidad(velocidad_0_to_1023, direccion);
// Trabajas con el vector que está en memoria montón
free(velocidades);
return 0;
}
In the example, you get a vector using dynamic memory by calling the function velocidadyou use it for calculations, print it, whatever you want to do; and then release it by function free.Third versionAs suggested https://es.stackoverflow.com/users/105299/mrdave1999 , a third option is to pass the address of an existing vector to the function, so that you may not use dynamic memory and you do not need to wrap the vector in a structure.void velocidad(uint16_t velocidad_0_to_1023, uint8_t direccion, uint8_t * velocidades)
{
if (velocidad_0_to_1023 > 1023) velocidad_0_to_1023 = 1023;
uint8_t velocidad_L = (uint8_t) 0x00FF & velocidad_0_to_1023;
uint8_t velocidad_H = (uint8_t) ((0x00FF & (velocidad_0_to_1023 >> 8)) | direccion);
velocidades[0] = 0x20;
velocidades[1] = velocidad_L;
velocidades[2] = velocidad_H;
}
int main(int argc, char * argv[]) {
uint16_t velocidad_0_to_1023;
uint8_t direccion;
// Obtenemos los datos que vamos a pasar a la función
uint8_t destino[3];
velocidad(velocidad_0_to_1023, direccion, destino);
// Trabajas con el vector que está en la pila del main
return 0;
}
A final note, following the last doubt raised as a comment.Any local variable to a function is destroyed/freed upon completion of this function. Therefore, a way to save the data generated in a function is to return a copy, as it is done when you invoke return variablefor any primitive variable or structure.Another way is to create the variable outside, and as in this case, pass the memory address to the function, so that the function fills it with data.Besides, I think you have a confusion about creating vectors or variables in general. And it's just that declaring a variable doesn't need to initialize it.If you declare the following:int x;
int vector[10];
Only by the mere fact of declaring a primitive variable, as x, memory is reserved for that variable. And when you declare a fixed-size vector, like vector[10]also reserves sufficient space for so many elements of the type you have indicated. In both cases it is not necessary to give initial values to the variables.However, it is very important that you control the variables and when they will receive information, because C does not initialize the variables to any value. That is, a memory area is assigned for that variable, and the value it contains can be any number. For example, if another application used that address, and at the end of running you are assigned that same address for some variable, your variable may initially contain the value it had for the use of the interior application.To this, communally, we tend to refer as values garbage.Therefore, by declaring the speed vector in the main, reserves space for 3 data, and these contain any garbage values. Then you pass the memory address where the vector begins so that the function fills with valid information the vector, about writing the garbage values.Finally, because of the garbage values, it is good practice to give an initial value to your variables, less in cases where you know that you will start them later and you will not use their value between their statement and their refill.