zabawy_pamiecia.c

/*
 * plik ma na celu zobrazowanie sposobu alokacji pamięci w systemie Linux
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char * napis = "Ala ma kota";
int a;
unsigned int * wsk;
unsigned char * wsk2;


main(int argc, char *argv[], char *envp[]) {
  printf("adresy zmiennych przekazywane do main()\n");
  printf("\t%x %x %x\n", &argc, &argv, &envp);
  printf("zmienne przekazywane do main()\n");
  printf("\t%x %x %x\n", argc, argv, envp);
  // warto zauważyć że envp jest kontynuacją argv - nic ich nie odziela w pamięci ...
  printf("napisy na które wskazują\n");
  printf("\t%x %x %x\n", argv[0], envp[0], envp[1]);
  
  printf("\n\n");
  
  
  printf("fragment stosu związany z main()\n");
  for (wsk=&argc; wsk<argv[0]; wsk++)
    if (*wsk != 0)
      printf("%x : %x\n", wsk, *wsk);
  // tutaj zaczynają się tablice char
  for (wsk2=argv[0]; wsk2<argv[0]+20; wsk2++)
    printf("%x : %x (%c)\n", wsk2, *wsk2, *wsk2);
  
  printf("\n\n");
  
  
  int b;
  int c;
  printf("alokacja zmiennej globalnej a lokalnej\n");
  printf("\t%x %x %x\n", &a, &b, &c);
  // warto zwrocic uwage iż zmienna lokalna jest zaalokowana na stosie przed
  // tablicami będącymi argumentami main(), a zmienna globalna poza stosem
  // kolejne zmienne alokowane są coraz bradziej przed (stos rośnie w dół)
  // jeżeli którąś z tych zmiennych będzie tablica, a następnie przekroczymy jej zakres
  // będziemy zamazywać kolejne obszary pamięci w stronę wyższych adresów (argumenty main, ...)
  // jest to tak zwany błąd przepełnienia bufora - http://pl.wikipedia.org/wiki/Przepełnienie_bufora
  
  // warto także zwrócić uwagę iż taka metoda alokacji tablic narzuca ograniczenie na ich rozmiar
  // związane z ograniczeniem rozmiaru stosu, dlatego lepiej duże tablice alokować poza stosem
  char d[100];
  char e[atoi(argv[1])];
  
  // gdy jako agrument podamy np. 20000000 (20MB)
  // program zakończy się naruszeniem ochrony pamięci
  printf("alokacje tablic\n");
  printf("\t%x %x %x\n", &c, d, e);
  
  // natomiast alokacja mallociem ponad 20 razy większej tablicy jest nieszkodliwa
  char * tab = malloc(sizeof(*tab) * 400000001 );
  tab[1] = 20;
  tab[400000000]=30;
  printf("\t%x %x %d %d\n", &tab[1], &tab[400000000], tab[1], tab[400000000]);
  
  // a na koniec napis - jest to w zasadzie tablica, ale jakiego rodzaju ?
  char *bo;
  bo = strstr (napis, "kota");
  
  printf("DLUGOSC NAPISU poprzez wskazniki (niezupelnie napisu dla kodowan typu UTF8)\n");
  printf("\t%x %x %i\n", napis, bo, (int)((unsigned int)bo - (unsigned int)napis));
}

XHTML generated by highlight (http://www.andre-simon.de/) from zabawy_pamiecia.c



Copyright (c) 1999-2015, Robert Paciorek (http://www.opcode.eu.org/), BSD/MIT-type license


Redystrybucja wersji źródłowych i wynikowych, po lub bez dokonywania modyfikacji JEST DOZWOLONA, pod warunkiem zachowania niniejszej informacji o prawach autorskich. Autor NIE ponosi JAKIEJKOLWIEK odpowiedzialności za skutki użytkowania tego dokumentu/programu oraz za wykorzystanie zawartych tu informacji.

This text/program is free document/software. Redistribution and use in source and binary forms, with or without modification, ARE PERMITTED provided save this copyright notice. This document/program is distributed WITHOUT any warranty, use at YOUR own risk.

Valid XHTML 1.1 Dokument ten (URL: http://www.opcode.eu.org/programing/c_cpp/zabawy_pamiecia.c) należy do serwisu OpCode. Autorem tej strony jest Robert Paciorek, wszelkie uwagi proszę kierować na adres e-mail serwisu: webmaster@opcode.eu.org.
Data ostatniej modyfikacji artykulu: '2014-01-07 19:27:41 (UTC)' (data ta może być zafałszowana niemerytorycznymi modyfikacjami artykułu).