Hỏi về cấp phát bộ nhớ động trong C

Em chào anh chị trong diễn đàn ạ.
Em đang làm một bải tập về cấp phát bộ nhớ động với C.
Em thử chạy thử code thì với giá trị nhập vào < = 5 thì code chạy bình thường nhưng khi em nhập vào giá trị lớn hơn 5 thì gặp lỗi.
Em đã thử dubug bằng visual studio rồi nhưng vẫn không hiểu là lỗi gì.
Mong mọi người xem giúp với ạ.
code :

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 void arr_input(int *arr, int sz){
	for(int i = 0; i < sz; i++){
		printf("Nhap vao phan tu thu %d: ", i+1);
		scanf("%d",arr+i);
	}
 }
 void arr_output(int *arr, int sz){
	printf("\nCac phan tu cua mang la: ");
	for(int i = 0; i < sz; i++){
		printf(" %d",*(arr+i));
	}
	printf("\n");
 }
 void insert_first_arr(int* arr, int* n, int x){
	*n+=1;
	arr = (int*)realloc(arr,*n);
	if(arr==NULL){
		printf("Khong du bo nho.");
		return;
	}
	else{
		printf("Cap phat bo nho thanh cong. \n");
	}
	for(int i = *n-1; i >=0;i--){
		*(arr+i) = *(arr+i -1);
	}
	*arr = x;
 }
  
int main(){

	printf("\t\t\t Thao tac voi mang mot chieu.");
	int sz;
	printf("\nNhap vao kich thuoc cua mang: ");scanf("%d",&sz);
	int *arr = NULL;
	arr = (int*)malloc(sz*sizeof(int));
	if(arr==NULL){
		printf("Khong du bo nho.\n");
		exit(1);
	}
	else{
		memset(arr,NULL,sz*sizeof(int));
		printf("Cap phat bo nho thanh cong. \n");
	}
	arr_input(arr,sz);
	arr_output(arr,sz);
	
	insert_first_arr(arr,&sz,5);
	
	printf("Mang sau khi them gia tri la: ");
	arr_output(arr,sz);
	
	if(arr!=NULL){
		free(arr);
		arr =NULL;
	}
	
	getchar();
	return 0;
}

Em cảm ơn mọi người ạ.

Format lại code bạn nhé. Thêm 3 dấu ` vào đầu và cuối code.

1 Like

Cảm ơn nhiều ạ. :smiley:

ngó qua thấy dòng này có số 5 này :smiley:
insert_first_arr(arr,&sz,5);

5 là giá trị để thêm vào đầu mảng bạn ạ. Nó không ảnh hưởng đến kích thước mảng bị giới hạn <= 5.

Bác nào xem hộ mình cái, mình không code quen con trỏ lắm. Hình như ở đây thiếu &?

Bạn sai ở dòng này. Check lại reference nhé :smiley:

http://en.cppreference.com/w/c/memory/realloc

Và để ý thì ở dòng trên nó sai hơn 1 lỗi, lỗi thứ 2 có thể gẫn tới memory leak nhé :smile:

3 Likes

Cảm ơn bạn nhiều ạ. Lỗi đúng ở đó :smiley: Code chạy bình thường rồi.

Không bạn ạ. arr+i là địa chỉ. Truyền vào địa chỉ đúng rồi. :grinning:

Dòng *n+=1 à bạn. Nên để thành (*n)++ à bạn. :smile:

Dòng arr = (int *) realloc(arr, *n); có lỗi là do bạn cấp phát *n bytes nhưng thực tế cần (*n) * sizeof(int) bytes lận (vì 1 biến int chiếm 4 bytes - còn theo tùy máy 32bits hay 64bits).
Bạn đang thu hẹp bộ nhớ thay vì mở rộng nó :joy: (cái này chắc bạn sửa được rồi).

Trong link của anh @drgnz, có dòng là:

The reallocation is done by either:
a) expanding or contracting the existing area pointed to by ptr, if possible.
The contents of the area remain unchanged up to the lesser of the new and old
sizes. If the area is expanded, the contents of the new part of the array are
undefined.
b) allocating a new memory block of size new_size bytes, copying memory area
with size equal the lesser of the new and the old sizes, and freeing the old
block.

Nếu may mắn hoặc chương trình nhỏ, các ô nhớ trống kề bên nhau thì realloc như bạn là không thành vấn đề do địa chỉ của arr không thay đổi. Nhưng thử realloc với 10000 * sizeof(int) thì chương trình chạy ra giá trị rác cho coi :v (mình mới thử xong nên comment lưu ý luôn).

2 Likes

Cảm ơn ban nhiều. T cũng mới học phần con trỏ với cấp phát động nên ngu ngơ : )). Bảo sao t thử với 5 thì code chạy ngon lành mà thử lớn hơn thì lỗi :smile:

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?