2010/03/21

Dynamic Memory Allocation in C and C++ (malloc, new, and vector)

1. C version - one dimension array
#include <stdlib.h> // for malloc, realloc, free

#include

<stdio.h>

/*

void * malloc ( size_t size );

- Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.

*/

/*

void free ( void * ptr );

- Deallocate space in memory previously allocated using a call to malloc,

- calloc or realloc is deallocated, making it available again for further allocations.

*/

/*

void * realloc ( void * ptr, size_t size );

- Reallocate memory block.

- The content of the memory block is preserved up to the lesser of the new and old sizes.

- If the new size is larger, the value of the newly allocated portion is indeterminate.

*/

int

main()

{

int size = 10;

// dynamically allocate a memory block with size x sizeof(int)

int *arr = (int*)malloc(size * sizeof(int)); // the same as (int*) calloc (size, sizeof(int));

printf("address of arr is %X\n",arr);

for (int i = 0; i < size ; i++){

arr[i] = 1; // Treat the memory block as a array

}

arr = (int*)realloc (arr ,2 * size * sizeof(int)); // Reallocate memory block

printf("address of arr is %X\n",arr);

for (int i = 0; i < 2*size ; i++){

printf("arr[%d]=%d\n",i,arr[i]); // arr[0~9] is 1. arr[10~19] is indeterminate.

}

free(arr); // Deallocate space

return 0;

}

2. C version - two dimension array - pointer to pointer
#include <stdlib.h>

#include

<stdio.h>

#include

<time.h>

/*

int **arr ----> |------|

                      | int* | ---> | int int |

                      | int* | ---> | int int |

                      | int* | ---> | int int |

                      |------|

                                           ||

                                           ||

                                           ||

                                          \/

                               m x n 2-D array

*/

int

main()

{

int m = 3 , n = 2; // m x n matrix

int **arr; // pointer to pointer (double pointer)

arr = (int**)malloc(m * sizeof(int*)); // sizeof(int*): the size of int pointer instead of int

for (int i = 0; i < m ; i++)

{

arr[i] = (int*)malloc(n * sizeof(int));

// arr[i] is the same as *(arr+i). Ex:

// *(arr+i) = (int*)malloc(n * sizeof(int));

}

srand(time(NULL));

for (int i = 0; i < m ; i++)

{

for (int j = 0; j < n ; j++)

{

arr[i][j] = rand()%10; // Treat double pointer as 2-D array

// *(*(arr+i)+j) = rand()%10;

printf("%d\t",arr[i][j]);

}

printf("\n");

}

// We should not forget to free the memory which we have allocated dynamically,

// starting from the lowest level. i.e, in the reverse order of allocations.

// If we free up the higher level pointers first the lower level pointers would be lost

// and we would not be able to free up the memory allocated to those pointers.

// This would lead to memory leaks. Given below is how we should free up the memory.

for (int i = 0; i < m ; i++){

free(arr[i]);

}

free(arr);

return 0;

}

3. C++ version - one dimension array
#include <cstdlib>

#include

<cstdio>

#include

<iostream>

using

namespace std;

// Type *array = new Type(size);

// delete array;

int

main()

{

int size = 10;

int *arr = new int[size]; // array with size = 10

int *p = new int(5); // a int with parameter 5. That is, *p is 5.

for (int i = 0; i < size ; i++){

arr[i] = 1; // Treat the memory block as a array

}

/*

Reallocate.

- In contrast to C's realloc, it is not possible to directly reallocate memory allocated with new[].

- To extend or reduce the size of a block, one must allocate a new block of adequate size,

- copy over the old memory, and delete the old block.

- The C++ standard library provides a dynamic array that can be extended or reduced in its std::vector template.

*/

delete[] arr; // Arrays allocated with new[] must be deallocated with delete[].

delete p;

return 0;

}

4. C++ version - two dimension array - pointer to pointer
#include <cstdlib>

#include

<cstdio>

#include

<ctime>

#include

<iostream>

using

namespace std;

/*

int **arr ----> |------|

                      | int* | ---> | int int |

                      | int* | ---> | int int |

                      | int* | ---> | int int |

                      |------|

                                           ||

                                           ||

                                           ||

                                          \/

                               m x n 2-D array

*/

int

main()

{

int m = 3 , n = 2;

int **arr;

arr = new int*[m];

for (int i = 0; i < m ; i++){

arr[i] = new int[n];

}

srand(time(NULL));

for (int i = 0; i < m ; i++)

{

for (int j = 0; j < n ; j++){

arr[i][j] = rand()%10;

cout << arr[i][j] << "\t";

}

cout << endl;

}

for (int i = 0; i < m ; i++){

delete[] arr[i];

}

delete[] arr;

return 0;

}

5. C++ version - standard template library (STL) - vector - one and two dimension array
#include <vector>

#include

<string>

#include

<iostream>

using

namespace std;

int

main()

{

/* Case #1 - 1D vector */

vector<int> vector_1D;

vector_1D.push_back(5);

vector_1D.push_back(6);

vector_1D.push_back(7);

/* vector_1D has | int int int | */

for(int i=0;i<(int)vector_1D.size();i++)

cout << vector_1D[i] << endl;

vector_1D.clear(); // Actually, we don't need to delete allocated space.

// Vector will delete it for us when vector_1D is out of the scope.

/* Case #2 - 2D vector*/

int m=3, n=2;

vector<vector<int>> vector_2D;

vector_2D.resize(m); // there are m vector<int> variables

for (int i = 0; i < (int)vector_2D.size() ; i++){

vector_2D[i].resize(n);

}

/*

vector_2D has | vector<int> vector<int> vector<int> |

                              ||                   ||                  ||

                              ||                   ||                  ||

                              \/                  \/                  \/

                   has |int int|       has |int int|        has |int int|

*/

for (int i = 0; i < (int)vector_2D.size(); i++){

for (int j = 0; j <(int)vector_2D[i].size() ; j++){

vector_2D[i][j] = rand()%10;

cout << vector_2D[i][j] << "\t";

}

cout << endl;

}

return 0;

}

沒有留言:

2024年React state management趨勢

輕量化 在過去Redux 是 React 狀態管理的首選函式庫。 Redux 提供了強大的功能和靈活性,但也帶來了一定的學習成本和複雜度。 隨著 React 生態的不斷發展,越來越多的開發者開始追求輕量化的狀態管理函式庫。 Zustand 和 Recoil 等庫以其簡單易用、性...