I spend a lot of time trying to find out why I have an assert in this code.
If there is no destructor in the class, it's work well.
Can you explaine, why I have an Assert whit the class containing destructor.
I dont want to know the number of element in the array. I Just want to understand the Assert when there is a destructor in the class.
With Visual C++, the "new" call the "malloc" function.
=====================================================================================
More detail:
With: CTheClass* pArrayTheClass = new CTheClass[1];
In debug, in the _heap_alloc_dbg_impl() function,
you can find the following line of code:
blockSize = sizeof(_CrtMemBlockHeader) + nSize + nNoMansLandSize;
where:
sizeof(_CrtMemBlockHeader) : 32
nSize : 4
nNoMansLandSize : 4
After that, the memory is allocated (withHeaderBlock),
and the function return the pointer to the data part.
And at the end of "operator new[] " in the "new2.cpp" file,
this data pointer is return, to the program allocation.
But
With:
CTheClassWithDestructor* pArrayTheClassWithDestructor = new CTheClassWithDestructor[1];
is nearly the same thing...
but the nSize is equal to 8; sizeof( int) + 4 bytes
But this time, even if at the end of "operator new[] we have the dataPart pointer.
In the main program I receive this pointer with an offset of 4.
And if I substract 4 from the pointer there is no assert when I call the _msize() function.
That explain the Assert.
The assert is cause bt this offset of 4.
But why we have this offset of 4 ?
Conclusion
This offset of 4 bytes contain the number of element.
If the class have a destructor, the compiler reserve 4 bytes to hold the number of elements in the array.
If there is no destructor to call, we don't have this extra 4 bytes as offset.
Thank's
Marc
#include <malloc.h>
class CTheClass
{
private:
int TheValue_;
};
class CTheClassWithDestructor
{
public:
~CTheClassWithDestructor()
{
int TheValue_ = 0;
}
private:
int TheValue_;
};
int _tmain(int argc, _TCHAR* argv[])
{
int size;
CTheClass* pArrayTheClass = new CTheClass[1];
size = _msize(pArrayTheClass);
delete [] pArrayTheClass;
CTheClassWithDestructor* pArrayTheClassWithDestructor
= new CTheClassWithDestructor[1];
size = _msize(pArrayTheClassWithDestructor); /// ASSERT On this line
delete [] pArrayTheClassWithDestructor;
return 0;
}
With Visual C++, new calls the malloc function.
This is partially true: the new expressions in your code do call operator new to allocate memory and operator new does indeed call malloc. But the pointer to the initial element that is yielded by the new expression is not necessarily the pointer obtained from malloc.
If you dynamically allocate an array of objects that require destruction (like your CTheClassWith_string type), the compiler needs to keep track of how many elements are in the array so that it can destroy them all when you delete the array.
To keep track of this, the compiler requests a slightly larger block from malloc then stores some bookkeeping information at the beginning of the block. The new expression then yields a pointer to the initial element of the array, which is offset from the beginning of the block allocated by malloc by the bookkeeping information.
Related
Because segmentation fault related to malloc/free happens, I would like to convert malloc/free to new/delete.
Error occurred when malloc/free is converted to below.
Let me know how to solve it.
(original)
char *only_valid_data = static_cast<char*> (malloc (data_size));
(converted)
char *only_valid_data = new static_cast<char*> [data_size];
Just do
char* only_valid_data = new char[data_size];
to allocate.
To free you do
delete[] only_valid_data;
Important note: When you allocate memory with new it will allocate data_size elements, not data_size bytes (like malloc does). The size of an element is the size of the non-pointer base type, in your case e.g. sizeof(*only_valid_data). In this case the element size and the byte size is the same (as sizeof(char) is specified to always be 1), but if the base type is something else it will make a big difference.
For example, if you do
int* int_ptr = new int[10];
then ten integers will be allocated, not ten bytes. This is equivalent to
int* int_ptr = reinterpret_cast<int*>(malloc(10 * sizeof(*int_ptr)));
Also note that for complex types, like structures and classes, allocating with new (or new[]) does more than just allocating memory, it will also make sure that the allocated object(s) constructor is called. The malloc function only allocates memory, it doesn't call the constructor.
Final note: The problem you have with the segmentation fault is probably not caused by your allocation, no matter how you allocate the memory. The problem is more likely because of something else, something you do not show in your question, like writing out of bounds of the allocated memory or dereferencing a null-pointer.
You need run your program in a debugger to catch the crash in action, it will allow you to examine the function call stack, and if the crash doesn't happen in your code then you walk up the call stack until you reach your code. There you can examine the values of variables, to help you understand why the problem occurred.
The malloc family (malloc, realloc, calloc, free) is used almost always in C code, as C++ provides the new and delete operators which are a lot more reliable to use.
A problem with malloc for allocation is that you must specify the size of the type in bytes that you want to allocate. For example:
int* ptr = malloc(5);
Will not allocate space for 5 integers in memory; it will allocate 5 bytes of memory (the size of an integer is 4 bytes, so this would obviously cause problems when assigning).
To do it properly, it must be written as
int* ptr = malloc(5 * sizeof(int));
So that 20 bytes are allocated.
However, there are some exceptions to the case. char, for example only requires one byte of memory, so doing
char* ptr = malloc(5);
Will allocate enough memory to hold 5 characters, and in a way is more valid that writing:
char* ptr = malloc(5 * sizeof(char)); //5 * sizeof(char) == 5 * 1 == 5
However, the free function does not need to know the size of the pointer to be deallocated; a void* is only needed.
Note that in C++, the return of malloc must be cast properly to the type wanted; malloc returns a void* type, but C++ does not allow any pointer to assign a void* to any pointer type like C does:
int* ptr = malloc(5 * sizeof(int)); //valid C code, invalid C++
int* ptr2 = (int*)malloc(5 * sizeof(int)); //valid C code, valid C++
In C++, the new[] operator resolves the issue of remembering to add the sizeof operator.
int* ptr = new int[5];//allocates 5 integers
int* ptr2 = new int(5);//be careful: this allocates a single integer with value of 5
Note that if the new[] operator has been used, the delete[] operator must be used. Otherwise the delete operator must be used:
int* ptr = new int[5];//allocates 5 integers
delete[] ptr;//deallocate the 5 integers
int* ptr2 = new int(5);//be careful: this allocates a single integer with value of 5
delete ptr;//deallocate the integer
The problem with your code is that it does not fit the syntax of the new[] operator
The syntax could be described as:
T* p = new T[size];
Thus your code:
char *only_valid_data = new static_cast<char*> [data_size];
Should be corrected to:
char *only_valid_data = new char[data_size];
As static_cast<char*> is not a type.
Hope this helps :)
here is the class that I am using.
#include<stdio.h>
#include <string.h>
class EnDe{
private:
int *k;
char *temp;
public:
char * EncryptString(char *str);
char * DecryptString(char *str);
EnDe(int *key);};
EnDe::EnDe(int *key){
k=key;
}
char * EnDe::EncryptString(char *str){
int t=2;
t=(int)k[1]*(int)2;
for (int i=0;i<strlen(str);i++){
temp[i]=str[i]+k[0]-k[2]+2-k[1]+k[3]+t;
}
char alp=k[0]*57;
for (int y=strlen(str);y<strlen(str)+9;y++){ //--*
temp[y]=alp+y; //--*
}
temp[(strlen(str)+9)]='\0'; //--*
return temp;
}
char * EnDe::DecryptString(char *str){
int t=2;
t=k[1]*2;
for (int i=0;i<strlen(str);i++){
temp[i]=str[i]-t-k[3]+k[1]-2+k[2]-k[0];
}
temp[(strlen(str)-9)]='\0';
return temp;
}
And here is the main program.
#include <stdio.h>
#include "EnDe.h"
int main(void){
char *enc;
char op;
printf("\nE to encrypt and D to decrypt");
int opi[4]={1,2,9,1};
EnDe en(opi);
strcpy(enc,en.EncryptString("It is C's Lounge!! "));
printf("Encrypted : %s",enc);
return 0;
}
Something is wrong with en.EncryptString function
when I run the program it stops working giving error and on removing strcpy(enc,en.EncryptString("It is C's Lounge!! ")); it runs. I want this problem to be resolved.
char *enc;
strcpy(enc,en.EncryptString("It is C's Lounge!! "));
You don't provide any space for the copy - enc doesn't point anywhere.
You never allocate any memory.
When you say
char *foo;
You tell the compiler that you want to store a memory address to some data somewhere, but not that you also want to store some data. Your class stores two pointers (int *k and char *temp) that never get any memory assigned to them, and so does your main function with char *enc. This can never work.
In C and C++, there are two modes of memory allocation: one is stack-based allocation, where you declare variable names in a function, and the compiler or the runtime will automatically allocate and release memory for you; the other is heap-based allocation, where you use malloc or new to allocate memory at run time, and must manually release that memory again with delete or free.
A pointer is "just" a stack-allocated variable that contains the address of another memory location. If you don't assign any value to a pointer, it points to invalid memory, and whatever you try to do with it will fail. To fix your program, you must make sure that every pointer points to valid memory. If you want it to point to a stack-based variable, you use the address-of operator:
int val = 4;
int *pointer_to_val = &val;
/* the pointer_to_val variable now holds the address of the val variable */
If you don't want it to point to a stack-allocated variable, you must allocate the memory yourself.
In C++, heap memory is allocated with the new operator, like so:
ClassType *instance = new ClassType(arg1, arg2)
where ClassType is the type of the class you're creating an instance of, instance is the pointer where you want to store the address of the instance you've just created, and arg1 and arg2 are arguments to the ClassType constructor that you want to run.
When you no longer need the allocated memory, you use delete to release the memory:
delete instance;
Alternatively, you can also use the C-style malloc and free functions. These are not operators; they are functions which return the address of the allocated memory. They do not work for C++ class instances (since you do not run the constructor over the returned memory), but if you want to run a pure-C program, they're all you have. With malloc, you do as follows:
char* string = malloc(size);
where string is the pointer for which you want to allocate memory, and size is the number of bytes you want the system to allocate for you. Once you're ready using the memory, you release it with free:
free(string);
When calling delete or free, it is not necessary to specify the size of the object (the system remembers that for you). Note, however, that you must make sure to always use delete for memory allocated with new, and to always use free for memory allocated with malloc. Mixing the two will result in undefined behaviour and possibly a crash.
I am new to programming and I am trying to understand the difference between
A = (char * ) malloc(sizeof(char)*n);
and
A = (char * ) malloc(sizeof(char));
or
A = new char [n];
and
A = new char;
What is the default memory that a compiler is allocating to this pointer, when I do not specify the number of objects of particular data type.
Also when I declare
A = new char [n];
cout << A[n+1];
it does not give me a segmentation fault.
Should It not give segmentation fault because I am trying to access memory beyond what has been allocated for the Array.
Memory is not "allocated to this pointer", it's allocated and then you get a pointer to the memory.
This:
char *a = malloc(sizeof(char) * n);
is the same as
char *a = malloc(n);
since sizeof(char) is always 1. They both allocate space for n characters worth of data, and return a pointer to the location where the first character can be accessed (or NULL on failure).
Also, the casts are not needed in C, you should not have any.
Since sizeof(char) is 1, the second call is equivalent to:
char *a = malloc(1);
which means it allocates a memory block of size 1. This is of course distinct from the pointer to that memory block (the value that gets stored in the pointer variable a). The pointer is most likely larger than 1 char, but that doesn't affect the size of the block.
The argument to malloc() specifies how many chars to allocate space for.
I ignored the new usage, since that is C++ and the question is tagged C.
A = (char * ) malloc(sizeof(char)*n);
This allocates space for n characters.
A = (char * ) malloc(sizeof(char));
This allocates memory for 1 character.
Every call to malloc allocates memory in the heap.
The other code is C++, and it's exactly the same, except that it will use stack memory if A is a local variable. Accessing A[n+1] may or may not yield a segfault. A[n+1] can reference a memory address that you are allowed to use. Segfault happens when you go out of the region of memory you can access, and the way it works is that there is a "red zone" from which it is considered you accessed invalid memory. It may be the case that A[n+1] just isn't "invalid enough" to trigger a segfault.
allocate space for N characters (N should be some positive integer value here)
char *ma = (char * ) malloc(N);
char *na = new char [N];
don't forget to release this memory ...
delete [] na;
free(ma);
allocate space for a single character
char *mc = (char * ) malloc(sizeof(char));
char *nc = new char;
Now, as the others have pointed out, you tagged this C, but half your code is C++. If you were writing C, you couldn't use new/delete, and wouldn't need to cast the result of malloc.
Oh, and the reason you don't get a segmentation fault when you read off the end of your array is that this is undefined behaviour. It certainly could cause a SEGV, but it isn't required to check, so may appear to work, at least some of the time, or fail in a completely different way.
Well, the compiler doesn't allocate memory for the data. Only the pointer which is either 4 or 8 bytes depending on your architecture.
There is no difference between the first two and the last two in terms on functionality. Most C++ libraries I've seen use malloc internally for new.
When you run the code to allocate n characters and you print out the n + 1th character, you aren't getting a segmentation fault most likely because n isn't a multiple of some number, usually 8 or 16. Here's some code on how it might do that:
void* malloc(size_t size) {
if (size & 0x7 != size)
size = size & 0x7 + 1;
return _malloc(size);
}
So, if you requested, say, 5 bytes, malloc would actually allocate, with that code, 8 bytes. So, if you request the 6th byte (n + 1), you would get garbage, but it is still valid memory that your program can access.
I've been reading through some books, and when it comes to Class/Functions using Pointers/Dynamic Memory (or heap or w/e they call it) I start to get confused.
Does anyone have a simple....like easy example they can show, because the books im using are using overly complex examples (large classes or multiple functions) and it makes it hard to follow. Pointers have always been my weak point anyways but I understand BASIC pointers, just classes/functions using them is a little bit confusing.
Also.....when would you use them is another question.
Stack allocation:
char buffer[1000];
Here the 1000 must be a constant. Memory is automatically freed when buffer goes out of scope.
Heap Allocation:
int bufsz = 1000;
char* buffer = new char[bufsz];
//...
delete [] buffer;
Here bufsz can be a variable. Memory must be freed explicitly.
When to use heap:
You don't know how much space you will need at compile time.
You want the memory/object to persist beyond the current scope.
You need a large chunk of memory (stack space is more limited than heap space)
Your computer's RAM is a big pile of bytes ordered one after another, and each one of those bytes can be accesed independently by it's address: an integer number startig from zero, upwards. A pointer is just a variable to hold that address of a single place in memory.
Since the RAM is a big chunk of bytes, the CPU ussually divides that big pile of bytes on several chunks. The most important ones are:
Code
Heap
Stack
The Code chunk is where the Assembly code lies. The Heap is a big pool of bytes used to allocate:
Global variables
Dynamic data, via the new operation on C++, or malloc() on C.
The stack is the chunk of memory that gets used to store:
Local variables
Function parameters
Return values (return statement on C/C++).
The main difference between the Stack and Heap is the way it is used. While the Heap is a big pool of bytes, the Stack "grows" like a stack of dishes: you can't remove the dish on the bottom unless there are no more dishes on it's top.
That's how recursion is implemented: every time you call a function recursively, memory grows on the stack, allocating parameters, local variables and storing return values of the returning functions, one on top of the others just like the stack of dishes.
Data living on the Stack have different "Life Span" than the data living on the Heap. Once a function exits, the data on the local variables get lost.
But if you allocate data on the Heap, that data won't get lost util you explicitly free that data with the delete or free() operations.
A pointer is basically a variable that contains the memory address of another variable (or in other cases to a function, but lets focus on the first).
That means that if I declare int[] x = {5,32,82,45,-7,0,123,8}; that variable will be allocated to memory at a certain address, lets say it got allocated on address 0x00000100 through 0x0000011F however we could have a variable which indicates a certain memory address and we can use that to access it.
So, our array looks like this
Address Contents
0x00000100 1
0x00000104 32
0x00000108 82
0x0000010B 45
0x00000110 -7
0x00000114 0
0x00000118 123
0x0000011B 8
If, for example, we were to create a pointer to the start of the array we could do this: int* p = &x; imagine this pointer variable got created a memory address 0x00000120 that way the memory at that address would contain the memory location for the start of array x.
Address Contents
0x00000120 0x00000100
You could then access the contents at that address through your pointer by dereferencing the pointer so that int y = *p would result in y = 1. We can also move the pointer, if we were to do p += 3; the pointer would be moved 3 addresses forward (note, however, that it moves 3 times the size of the type of object it is pointing to, here I am making examples with a 32 bit system in which an int is 32 bits or 4 bytes long, therefore the address would move by 4 bytes for each increment or 12 bytes in total so the pointer would end up pointing to 0x0000010B), if we were to dereference p again by doing y = *p; then we'd end up having y = 45. This is just the beginning, you can do a lot of things with pointers.
One of the other major uses is to pass a pointer as a parameter to a function so that it can do operations on certain values in memory without having to copy all of them over or make changes that will persist outside of the function's scope.
Warning: Don't do this. This is why we have vectors.
If you wanted to create an array of data, and return if from a function, how would you do it?
Obviously, this does not work:
int [10] makeArray(int val)
{
int arr[10];
for(int i=0; i<10; ++i)
arr[i] = val;
return arr;
}
You cannot return an array from a function. We can use pointers to refer to the first element of an array, like this:
int * makeArray(int val)
{
int arr[10];
for(int i=0; i<10; ++i)
arr[i] = val;
return &(arr[0]); // Return the address of the first element.
// Not strictly necessary, but I don't want to confuse.
}
This, however, also fails. arr is a local variable, it goes on the stack. When the function returns, the data is no longer valid, and now you have a pointer pointing to invalid data.
What we need to do is declare an array that will survive even after the function exits. For that, we use keyword new which creates that array, and returns the address to us, which needs to be stored in a pointer.
int * makeArray(int val)
{
int * arr = new int[10];
for(int i=0; i<10; ++i)
arr[i] = val;
return arr;
}
Then you can call that function and use that array like this:
int * a = makeArray(7);
for(int i=0; i<10; ++i)
std::cout << a[i] << std::endl;
delete [] a; // never forget this. Obviously you wouldn't do it right
// away like this, but you need to do it sometime.
Using pointers with new also gives you the advantage that you can determine the size of the array at runtime, something you can't do with local static arrays(though you can in C):
int * makeArray(int size, int val)
{
int * arr = new int[size];
for(int i=0; i<size; ++i)
arr[i] = val;
return arr;
}
That used to be one of the primary purposes for pointers. But like I said at the top, we don't do that anymore. We use vector.
One of the last vestiges of pointers is not for dynamic arrays. The only time I ever use them, is in classes where I want one object to have access to another object, without giving it ownership of that object. So, Object A needs to know about Object B, but even when Object A is gone, that doesn't affect Object B. You can also use references for this, but not if you need to give Object A the option to change which object it has access to.
(not tested, just writing down. and keeping things intentionally primitive, as requested.)
int* oneInt = new int; // allocate
*oneInt = 10; // use: assign a value
cout << *oneInt << endl; // use: retrieve (and print) the value
delete oneInt; // free the memory
now an array of ints:
int* tenInts = new int[10]; // allocate (consecutive) memory for 10 ints
tenInts[0] = 4353; // use: assign a value to the first entry in the array.
tenInts[1] = 5756; // ditto for second entry
//... do more stuff with the ints
delete [] tenInts; // free the memory
now with classes/objects:
MyClass* object = new MyClass(); // allocate memory and call class constructor
object->memberFunction("test"); // call a member function of the object
delete object; // free the object, calling the destructor
Is that what you wanted? I hope it helps.
I think this is what you're asking about:
Basically C++ doesn't allow variable-sized arrays. Any array in C++ has to be given a very specific size. But you can use pointers to work around that. Consider the following code:
int *arry = new int[10];
That just created an array of ints with 10 elements, and is pretty much the same exact thing as this:
int arry[] = int[10];
The only difference is that each one will use a different set of syntax. However imagine trying to do this:
Class class:
{
public:
void initArry(int size);
private:
int arry[];
};
void class::initArry(int size)
{
arry = int[size]; // bad code
}
For whatever reason C++ was designed to not allow regular arrays to be assigned sizes that are determined at runtime. Instead they have to be assigned sizes upon being coded. However the other way to make an array in C++ - using pointers - does not have this problem:
Class class:
{
public:
~class();
void initArry(int size);
private:
int *arry;
};
class::~class()
{
delete []arry;
}
void class::initArry(int size)
{
arry = new int[size]; // good code
}
You have to do some memory cleanup in the second example, hence why I included the destructor, but by using pointers that way you can size the array at runtime (with a variable size). This is called a dynamic array, and it is said that memory here is allocated dynamically. The other kind is a static array.
As far as 2-dimensional arrays go, you can handle it kind of like this:
Class class:
{
public:
~class();
void initArrays(int size1, int size2);
private:
int **arry;
};
class::~class()
{
delete [] arry[0];
delete [] arry[1];
delete [] arry;
}
void class::initArrays(int size1, int size2)
{
arry = new int*[2];
arry[0] = new int[size1];
arry[1] = new int[size2];
}
Disclaimer though: I haven't done much with this language in a while, so I may be slightly incorrect on some of the syntax.
I was reviewing a friend's code and got into an interesting debate on how C/C++ allocates memory on the stack and manages its release. If I were to create an array of 10 objects in a function, but return said array, does it release when the function pops (hence making the given data invalid) or is it placed into the heap (which raises the question of how do we release it?).
Sample code as follows:
Gene* GetTopTen()
{
// Create 10 genes (or 10 objects, doesn't matter)
Gene Ten[10];
// Sort out external pool data
Sort();
// Copy over data to the array of 10 objects
for(int i = 0; i < 10; Ten[i++] = pool[i]);
// Here is the core of my question:
return Ten;
}
Any help is greatly appreciated, this is turning into a very interesting question my friends and I can't answer.
That's a stack-allocated array, so the returned pointer is invalid.
Once the function returns, the data is not destroyed, but will likely be overwritten by the next function call. You may get lucky and it may still be there, but it is undefined behavior. You shouldn't rely on it.
Here is what may happen: during the function the stack looks like this:
"---------------------------
| caller function's data |
----------------------------
| Ten[9] |
| Ten[8] |
| ... |
| Ten[0] |
---------------------------"
Immediately after the function exits, it will probably look the same. But if the caller calls another function like this,
void some_func() {
Gene g;
...
}
the stack will now look like this:
"---------------------------
| caller function's data |
----------------------------
| g |
----------------------------
| Ten[8] |
| ... |
| Ten[0] |
---------------------------"
Some of the data may be silently overwritten (in this case it is Ten[9]), and your code will not know it. You should allocate the data on the heap with malloc() and explicitly free it with free().
That results in undefined behaviour. ten array is stored in the stack. Once the GetTopGene function ends, that stack is destroyed, so you shouldn´t use pointers to that part of memory.
What you want to do is allocate space in the heap.
Gene* GetTopTen(){
Gene* genes = (Gene*) malloc (10*sizeof(Gene));
//do stuff.
return genes;
}
You have to remember to free that memory once you are done with it.
Gene* genes = GetTopTen();
//do stuff with it.
free(genes);
This is the cause of the most hideous bugs! Sometimes it will work, other times it won't.
This is a bug, not a "clever piece of code".
Another way to do this correctly, without having to allocate heap memory, is to alter the function's prototype to take a pointer to the array to write the result into:
void GetTopTen( Gene Ten[] ) { ... }
then just delete the declaration of Ten in the function body since it's now a parameter.
The caller now needs to declare its own ten-element array and pass it as a parameter:
...
Gene top[10];
GetTopTen(top);
...
Just be careful that the caller declares a big enough array! Unfortunately C doesn't have a good way for the function to specify the size of the array that should be passed in, so the compiler won't warn you if the caller declares too small an array; it'll just overwrite the stack at runtime.
If you want to return an array from a function, you'll have to put it on the heap yourself:
In C
Gene* GetTopTen()
{
// Create 10 genes (or 10 objects, doesn't matter)
Gene *Ten = malloc(sizeof(Gene)*10);
....
// Now it's ok to return
return Ten;
}
int main()
{
Gene *genes = GetTopTen();
free (genes);
}
And in C++:
Gene* GetTopTen()
{
// Create 10 genes (or 10 objects, doesn't matter)
Gene *Ten = new Gene[10];
....
// Now it's ok to return
return Ten;
}
int main()
{
Gene *genes = GetTopTen();
delete [] genes;
}
Of course, it's also up to you to keep track of how long that array is, either by returning a length from GetTopTen in a pointer/reference parameter, or by some sort of constant.
Your function says it returns a pointer, so when your function is called, only space for a pointer is allocated on the stack for the return value. Therefore, your return value is a pointer that points to a place on the stack that will be invalid when your function exits.
Wrap your return value in a struct.
typedef struct
{
int Array[10];
} ArrayOfTen;
ArrayOfTen SomeFunction ()
{
ArrayOfTen array = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
return array;
}
int main (int argc, char *argv[])
{
ArrayOfTen array = SomeFunction ();
int i;
for (i = 0; i < 0; i++)
fprintf (stdout, "%d\n", array.Array[i]);
return 0;
}
This is not a bug, this is just a low level language. You (almost) cannot stack-allocate array and return it in the same function - until you are not one of the (un)luckies people. But also, you should not call malloc in every situation.
To make your program memory-friendly, allocate this array at stack in caller and pass it as argument.
GetTopTen function will then look:
void GetTopTen(Gene* genes) {
/*
Do something
Do not allocate new Gene array, you already have one - modify values at "genes" pointer
*/
}
Call it:
Gene genes[10];
GetTopTen(genes);
/*
Now, do whatever you want with top ten "genes", which are safe until return from this function
*/
This style, as I see nowadays, is not used, and it's very sadly that I am not joking, because this is in what low-level languages are diferent from these with garbage collection, and also lot faster than calling malloc() all the time; these variables are automatic deallocated and take less memory. But note that it depent on size of struct and number of elements - if it is really big, allocate it via malloc, othervise you can get stack overflow.