Skip to content

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

c
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));  // 30

Aslida arr[i] = *(arr + i) — compiler shunday yozadi.

2. Pointer + index

c
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)); // 40

p — array kabi ishlatish mumkin.

3. Massiv va pointer farqi

c
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 — pointer

Massiv nomi — const pointer (manzilni o'zgartirib bo'lmaydi).

4. Massiv funksiyaga

c
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

c
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

c
int arr[] = {10, 20, 30, 40, 50};
int *p = arr;

while (p < arr + 5) {
    printf("%d ", *p);
    p++;
}
// 10 20 30 40 50

p++ — keyingi elementga.

7. Misol: Massiv yig'indisi (pointer bilan)

c
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:

c
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);  // 15

8. malloc — dinamik xotira

Mavjud massivlar — kompilatsiya vaqtida hajmi ma'lum.

c
int arr[100];  // hajmi avval ma'lum

Dinamik — ish vaqtida hajm aniqlanadi:

c
#include <stdlib.h>

int n;
scanf("%d", &n);

int *arr = malloc(n * sizeof(int));  // n ta int uchun joy

9. malloc, free, NULL

c
#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 uchun

malloc → 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

c
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

c
int *arr = calloc(100, sizeof(int));  // 100 ta int, hammasi 0
// vs
int *arr = malloc(100 * sizeof(int)); // 100 ta int, axlat qiymatlar

calloc — biroz sekinroq, lekin xavfsizroq.

12. realloc — hajmni o'zgartirish

c
int *arr = malloc(10 * sizeof(int));
// ishlash...

// Yana 10 ta kerak
arr = realloc(arr, 20 * sizeof(int));

// Endi 20 ta element

13. To'liq misol

c
#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:

c
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

c
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

c
char *str = malloc(100);  // 100 ta char
strcpy(str, "Hello");
printf("%s\n", str);
free(str);

Yoki strdup (POSIX):

c
char *str = strdup("Hello");  // nusxa olish + malloc
free(str);

17. Pointer arrays — pointer massivi

c
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

c
int *p = malloc(10 * sizeof(int));
free(p);
*p = 42;  // CRASH — yo'q joyga yozish

Double free

c
int *p = malloc(10 * sizeof(int));
free(p);
free(p);  // CRASH yoki noma'lum xato

Yechim:

c
free(p);
p = NULL;  // ikkinchi `free` xavfsiz bo'ladi

Memory leak

c
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:

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:

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:

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:

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:

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:

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:

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:

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

bash
$ mkdir 5-oy-dars-7
$ git add . && git commit -m "feat: dars 7 - pointers and arrays" && git push

Lug'at

TerminIzoh
mallocMemory ALLOCation
callocCleared alloc (0 bilan)
reallocResize alloc
freeXotirani bo'shatish
Memory leakYo'qotilgan xotira
Dangling pointerYo'q joyga ko'rsatuvchi
Use after freefree dan keyin ishlatish
Double freeIkki marta free
HeapDinamik xotira joyi
StackLocal o'zgaruvchilar joyi
ValgrindMemory bug topish vositasi
NULL checkPointer'ni tekshirish

Keyingi dars

8-dars: String chuqurroq →

Master IT o'quv markazi — o'qitish rejasi