7-dars: Pointer va massiv
Dars haqida
Davomiyligi: 90 daqiqa Maqsad: Talaba pointer va massiv chuqur bog'liqligini tushunishi, dinamik xotira ajratish (malloc/free) ni o'rganishi kerak.
1. Massiv = pointer
int arr[5] = {10, 20, 30, 40, 50};
// Bu ikkalasi bir xil:
printf("%d\n", arr[0]); // 10
printf("%d\n", *arr); // 10
// Bu ham:
printf("%d\n", arr[2]); // 30
printf("%d\n", *(arr + 2)); // 30Aslida arr[i] = *(arr + i) — compiler shunday yozadi.
2. Pointer + index
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr; // & kerak emas — arr o'zi pointer
printf("%d\n", p[0]); // 10
printf("%d\n", p[2]); // 30
printf("%d\n", *(p + 3)); // 40p — array kabi ishlatish mumkin.
3. Massiv va pointer farqi
int arr[5];
int *p;
sizeof(arr); // 20 (5 * 4) — array hajmi
sizeof(p); // 8 (pointer hajmi)
arr = NULL; // XATO — array nomi const
p = NULL; // OK — pointerMassiv nomi — const pointer (manzilni o'zgartirib bo'lmaydi).
4. Massiv funksiyaga
void print_array(int arr[], int n) { // arr aslida int*
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}
// Bu ham ishlaydi:
void print_array(int *arr, int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}int arr[] = int *arr (C uchun bir xil).
5. sizeof xatosi
void func(int arr[10]) {
printf("%zu\n", sizeof(arr)); // 8 (pointer hajmi)
}
int main(void) {
int arr[10];
printf("%zu\n", sizeof(arr)); // 40 (array hajmi)
func(arr);
return 0;
}Funksiya ichida — hajmni bilmaymiz. Doim n parameter sifatida uzating.
6. Pointer arithmetic — massivda
int arr[] = {10, 20, 30, 40, 50};
int *p = arr;
while (p < arr + 5) {
printf("%d ", *p);
p++;
}
// 10 20 30 40 50p++ — keyingi elementga.
7. Misol: Massiv yig'indisi (pointer bilan)
int sum(int *arr, int n) {
int total = 0;
for (int i = 0; i < n; i++) {
total += *(arr + i); // yoki arr[i]
}
return total;
}Yoki:
int sum(int *start, int *end) {
int total = 0;
while (start < end) {
total += *start;
start++;
}
return total;
}
// Chaqirish
int arr[] = {1, 2, 3, 4, 5};
int s = sum(arr, arr + 5); // 158. malloc — dinamik xotira
Mavjud massivlar — kompilatsiya vaqtida hajmi ma'lum.
int arr[100]; // hajmi avval ma'lumDinamik — ish vaqtida hajm aniqlanadi:
#include <stdlib.h>
int n;
scanf("%d", &n);
int *arr = malloc(n * sizeof(int)); // n ta int uchun joy9. malloc, free, NULL
#include <stdlib.h>
int *arr = malloc(100 * sizeof(int));
if (arr == NULL) {
printf("Xotira yetmadi!\n");
return 1;
}
// ishlash
for (int i = 0; i < 100; i++) {
arr[i] = i * 2;
}
// MUHIM: bo'shatish
free(arr);
arr = NULL; // xavfsizlik uchunmalloc → free
malloc'dan keyin doim free kerak. Aks holda — memory leak.
Kichik dasturlarda — OS bo'shatadi. Lekin uzoq ishlovchi dasturlarda — RAM tugab qoladi.
10. malloc va array
int n = 1000;
int *arr = malloc(n * sizeof(int));
// Foydalanish — oddiy array kabi
for (int i = 0; i < n; i++) {
arr[i] = i;
}
// Bo'shatish
free(arr);11. calloc — 0 bilan to'ldirilgan
int *arr = calloc(100, sizeof(int)); // 100 ta int, hammasi 0
// vs
int *arr = malloc(100 * sizeof(int)); // 100 ta int, axlat qiymatlarcalloc — biroz sekinroq, lekin xavfsizroq.
12. realloc — hajmni o'zgartirish
int *arr = malloc(10 * sizeof(int));
// ishlash...
// Yana 10 ta kerak
arr = realloc(arr, 20 * sizeof(int));
// Endi 20 ta element13. To'liq misol
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
printf("Necha element: ");
scanf("%d", &n);
// Dinamik massiv
int *arr = malloc(n * sizeof(int));
if (arr == NULL) {
printf("Xotira yetmadi\n");
return 1;
}
// To'ldirish
for (int i = 0; i < n; i++) {
arr[i] = i * 10;
}
// Chiqarish
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Bo'shatish
free(arr);
return 0;
}14. Dynamic 2D array
Murakkab — pointer to pointer:
int rows = 3, cols = 4;
// Qatorlar uchun pointer'lar
int **matrix = malloc(rows * sizeof(int *));
// Har qator uchun ustunlar
for (int i = 0; i < rows; i++) {
matrix[i] = malloc(cols * sizeof(int));
}
// Foydalanish
matrix[1][2] = 42;
// Bo'shatish
for (int i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);15. Memory leak — eslatma
void leaky(void) {
int *p = malloc(100 * sizeof(int));
// free yo'q — leak!
}
int main(void) {
for (int i = 0; i < 1000; i++) {
leaky(); // har chaqirishda 400 byte yo'qoladi
}
return 0;
}1000 marta chaqirish — 400 KB yo'qoladi.
Yechim — doim free.
16. String va malloc
char *str = malloc(100); // 100 ta char
strcpy(str, "Hello");
printf("%s\n", str);
free(str);Yoki strdup (POSIX):
char *str = strdup("Hello"); // nusxa olish + malloc
free(str);17. Pointer arrays — pointer massivi
char *names[] = {"Akmal", "Aziza", "Botir", "Dilshod"};
int n = 4;
for (int i = 0; i < n; i++) {
printf("%s\n", names[i]);
}Bu — char pointerlarning massivi. Stringlar nomlarini saqlash uchun.
18. Common pitfalls
Use after free
int *p = malloc(10 * sizeof(int));
free(p);
*p = 42; // CRASH — yo'q joyga yozishDouble free
int *p = malloc(10 * sizeof(int));
free(p);
free(p); // CRASH yoki noma'lum xatoYechim:
free(p);
p = NULL; // ikkinchi `free` xavfsiz bo'ladiMemory leak
int *p = malloc(100);
p = malloc(200); // Birinchisi yo'qoldi!
free(p);19. Tools
Memory bug topish:
- Valgrind (Linux):
valgrind ./program - AddressSanitizer:
gcc -fsanitize=address - MallocStackLogging (macOS)
Bu — keyingi darslarda.
Darsdagi topshiriqlar
1 — Pointer va massiv
pointer-array.c:
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;
// 4 xil usulda chiqaring:
for (int i = 0; i < 5; i++) printf("%d ", arr[i]);
for (int i = 0; i < 5; i++) printf("%d ", *(arr + i));
for (int i = 0; i < 5; i++) printf("%d ", p[i]);
for (int i = 0; i < 5; i++) printf("%d ", *(p + i));2 — Funksiyaga pointer
func-ptr.c:
void modify(int *arr, int n) {
for (int i = 0; i < n; i++) {
arr[i] *= 2;
}
}
int main(void) {
int data[] = {1, 2, 3, 4, 5};
modify(data, 5);
// Tekshiring — qiymatlar o'zgardimi
}3 — Malloc asoslari
malloc-basic.c:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
printf("Necha element: ");
scanf("%d", &n);
int *arr = malloc(n * sizeof(int));
if (!arr) return 1;
for (int i = 0; i < n; i++) {
arr[i] = i * i;
}
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
return 0;
}4 — Dynamic input
dynamic-input.c:
Foydalanuvchi N kiritsin, keyin N ta raqam. Hammasini saqlang va statistika chiqaring.
5 — Realloc
realloc.c:
int capacity = 5;
int size = 0;
int *arr = malloc(capacity * sizeof(int));
// 10 ta element qo'shing
for (int i = 0; i < 10; i++) {
if (size == capacity) {
capacity *= 2;
arr = realloc(arr, capacity * sizeof(int));
}
arr[size++] = i;
}
// Chiqaring
for (int i = 0; i < size; i++) printf("%d ", arr[i]);
free(arr);Dynamic array (vektor) tushunchasi.
6 — Pointer arithmetic
pointer-arith.c:
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *start = arr;
int *end = arr + 10;
// Yig'indini topish faqat pointer bilan
int sum = 0;
while (start < end) {
sum += *start;
start++;
}7 — String massiv
string-array.c:
char *days[] = {"Dushanba", "Seshanba", "Chorshanba",
"Payshanba", "Juma", "Shanba", "Yakshanba"};
for (int i = 0; i < 7; i++) {
printf("%d: %s\n", i + 1, days[i]);
}8 — Dynamic 2D
dynamic-2d.c:
int rows = 5, cols = 5;
int **matrix = malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++) {
matrix[i] = malloc(cols * sizeof(int));
}
// To'ldirish
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = i * cols + j;
}
}
// Chiqarish
// ...
// Free
for (int i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);9 — Memory leak test
leak-test.c:
#include <stdlib.h>
void leak(void) {
int *p = malloc(1000 * sizeof(int));
// free yo'q
}
int main(void) {
for (int i = 0; i < 100; i++) {
leak();
}
return 0;
}Mac'da: Activity Monitor'da RAM oshganini ko'ring.
Linux'da: valgrind ./leak-test — leak hisobi.
Tuzating: free(p) qo'shing.
10 — GitHub
$ mkdir 5-oy-dars-7
$ git add . && git commit -m "feat: dars 7 - pointers and arrays" && git pushLug'at
| Termin | Izoh |
|---|---|
| malloc | Memory ALLOCation |
| calloc | Cleared alloc (0 bilan) |
| realloc | Resize alloc |
| free | Xotirani bo'shatish |
| Memory leak | Yo'qotilgan xotira |
| Dangling pointer | Yo'q joyga ko'rsatuvchi |
| Use after free | free dan keyin ishlatish |
| Double free | Ikki marta free |
| Heap | Dinamik xotira joyi |
| Stack | Local o'zgaruvchilar joyi |
| Valgrind | Memory bug topish vositasi |
| NULL check | Pointer'ni tekshirish |