Putting cvector_push_back in a function causes undefined behaviour
TVKain opened this issue · comments
#include "cvector.h"
#include <stdio.h>
void foo(cvector_vector_type(int) *v)
{
cvector_vector_type(int) tmp = *v;
for (int i = 0; i < 100; ++i) {
cvector_push_back(tmp, i);
}
}
int main()
{
cvector_vector_type(int) v = NULL;
cvector_push_back(v, 1);
foo(&v);
printf("Size: %zu", cvector_size(v));
return 0;
}
The out put of the code above is:
Size: 101
But when i increase the loop count to 1000
#include "cvector.h"
#include <stdio.h>
void foo(cvector_vector_type(int) *v)
{
cvector_vector_type(int) tmp = *v;
for (int i = 0; i < 1000; ++i) {
cvector_push_back(tmp, i);
}
}
int main()
{
cvector_vector_type(int) v = NULL;
cvector_push_back(v, 1);
foo(&v);
printf("Size: %zu", cvector_size(v));
return 0;
}
The output is:
Size: 1854881427984
Also if I don't put the line cvector_push_back(v, 1); in main to initialize it then the output is:
Size: 0
I suspect memory leaks happen if cvector_push_back is used in another function
I just added *v = tmp;
at the end of your function and the output is Size: 1001
void foo(cvector_vector_type(int) *v)
{
cvector_vector_type(int) tmp = *v;
for (int i = 0; i < 1000; ++i) {
cvector_push_back(tmp, i);
}
*v = tmp;
}
tested with 1000000000 elements
With *v = tmp;
void foo(cvector_vector_type(int) *v)
{
cvector_vector_type(int) tmp = *v;
for (int i = 0; i < 1000000000; ++i) {
cvector_push_back(tmp, i);
}
*v = tmp;
}
Output:
Without *v = tmp;
void foo(cvector_vector_type(int) *v)
{
cvector_vector_type(int) tmp = *v;
for (int i = 0; i < 1000000000; ++i) {
cvector_push_back(tmp, i);
}
}
Output:
Direct access
void foo(cvector_vector_type(int) *v)
{
for (int i = 0; i < 1000000000; ++i) {
cvector_push_back((*v), i);
}
}
Note: using (*v)
not *v
Output:
Might be good to add a test for this once @eteran the maintainer has had a chance to review the pending PRs...
@TVKain Yea, because it's not "real objects", it does get a little funky when trying to create a vector in one function and then modifying it in another.
I certainly could update the documentation to mention the pitfalls, but it basically boils down to the macros editing the functions LOCAL variable on some resizes, which does not update the pointer in the caller's scope.
@K4zoku has identified this quirk and his recomendation is exactly what I would have said.
@andy5995 yup, the end of the year is a bit super busy because everyone at the office is trying to be productive before we all disappear for the holidays ;-). I'll definitely get through the pending PRs soon though!