» »

Niti - segmentation fault

Niti - segmentation fault

DubleG ::

/* sem_primer4.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <errno.h>
#include <sched.h>
#include <pthread.h> 
#include <math.h> 
#include <sched.h>
#include <string.h>
pthread_mutex_t izpis = PTHREAD_MUTEX_INITIALIZER;  
pthread_t tid[4];

/* V skupnem pomnilniku imamo lahko tudi strukturo */
typedef struct 
{
  char zakljuci_proces; /* Uporabimo za sinhronizacijo da vemo, kdaj zaključiti proces */
  char nizs[20];         /* Niz, v katerem bo ime najlepše */
}skupna_struktura;
/* Posamezni proces neprestano piše ime svoje kandidatke v skupni pomnilnik */
/* Posameznemu procesu sedaj podamo še identifikator semaforja */
void *nit1(void *args) {   
   int i=0;  
	 char niz[20]="Sneguljcica\0";
	skupna_struktura* kazalec = (skupna_struktura*)args;
	
     while (!kazalec->zakljuci_proces) /* Proces teče, dokler preko skupnega pomnilnika ne */
     {   
        pthread_mutex_lock(&izpis); /* Vstopimo v kritični odsek */      
        for (i=0; i<= strlen(niz); i++) /* Pišemo znak za znak, da malo upočasnimo program*/
    	{
      		kazalec->nizs[i]=niz[i];
      		sched_yield();                /* Za vsakim znakom prepustimo časovno rezino OS */
    	}
        pthread_mutex_unlock(&izpis); /* Izstopimo iz njega */   
      }
}
void *nit2(void *args) {   
   int i=0;
	char niz[20]="Trnjulcica\0"; 
skupna_struktura* kazalec = (skupna_struktura*)args;   

     while (!kazalec->zakljuci_proces) /* Proces teče, dokler preko skupnega pomnilnika ne */
     {   
        pthread_mutex_lock(&izpis); /* Vstopimo v kritični odsek */      
        for (i=0; i<= strlen(niz); i++) /* Pišemo znak za znak, da malo upočasnimo program*/
    	{
      		kazalec->nizs[i]=niz[i];
      		sched_yield();                /* Za vsakim znakom prepustimo časovno rezino OS */
    	}
        pthread_mutex_unlock(&izpis); /* Izstopimo iz njega */   
      }
}
void *nit3(void *args) {   
   int i=0;  
	char niz[20]="Pepelka\0";
skupna_struktura* kazalec = (skupna_struktura*)args; 

     while (!kazalec->zakljuci_proces) /* Proces teče, dokler preko skupnega pomnilnika ne */
     {   
        pthread_mutex_lock(&izpis); /* Vstopimo v kritični odsek */      
        for (i=0; i<= strlen(niz); i++) /* Pišemo znak za znak, da malo upočasnimo program*/
    	{
      		kazalec->nizs[i]=niz[i];
      		sched_yield();                /* Za vsakim znakom prepustimo časovno rezino OS */
    	}
        pthread_mutex_unlock(&izpis); /* Izstopimo iz njega */   
      }
}
void *nit4(void *args) {   
   int i=0;    
char niz[20]="Rdeča kapica\0"; 
skupna_struktura* kazalec = (skupna_struktura*)args; 

     while (!kazalec->zakljuci_proces) /* Proces teče, dokler preko skupnega pomnilnika ne */
     {   
        pthread_mutex_lock(&izpis); /* Vstopimo v kritični odsek */      
        for (i=0; i<= strlen(niz); i++) /* Pišemo znak za znak, da malo upočasnimo program*/
    	{
      		kazalec->nizs[i]=niz[i];
      		sched_yield();                /* Za vsakim znakom prepustimo časovno rezino OS */
    	}
        pthread_mutex_unlock(&izpis); /* Izstopimo iz njega */   
      }
}


int main()
{
  int shmid;
 
  /* Ustvarimo skupni pomnilnik viden le procesu in sinovom */
  shmid=shmget(100,sizeof(skupna_struktura*),IPC_CREAT | 0600);
  if (shmid<0)
  {
    perror("Napaka");
    return(errno);
  }

  
  
  printf("Racunalnik, racunalnik, v E-110 povej, katera najlepsa v dezeli je tej\n");

  int cpid;
  int f;

  skupna_struktura* kazalec;

  /* Dobimo kazalec na skupni pomnilnik */
  kazalec=(skupna_struktura*)shmat(shmid,(void *)0,0);
  kazalec->zakljuci_proces=0;

  

		pthread_create(&tid[0],0,nit1,(void*)kazalec);
	
		pthread_create(&tid[1],0,nit2,(void*)kazalec);
	
		pthread_create(&tid[2],0,nit3,(void*)kazalec);

	
		pthread_create(&tid[3],0,nit4,(void*)kazalec);
	
      	
      	shmdt(kazalec);
	
    
	
    /* V primeru, da je to oče, povečamo števec sinov za 1 */
    
  

  /* Počakamo 1 s */
  sleep(1);
  /* Nato pa izpišemo ime najlepše! */
 pthread_mutex_lock(&izpis);
  printf("%s\n",kazalec->nizs);
  pthread_mutex_unlock(&izpis);
  /* Sinovom sporočimo, naj se zaključijo! */
  kazalec->zakljuci_proces=1;

  /* Počakamo da se zaključijo */


  
  shmdt(kazalec);
  shmctl(shmid,IPC_RMID,0);

 
	pthread_join(tid[0],0);   
        pthread_join(tid[1],0);
	pthread_join(tid[2],0);   
    	pthread_join(tid[3],0);
  return 0;
}



Naloga vrže Segmentation fault.


PS: po odgovoru bom nalogo zbrisal, da ne bom kaznovan za plagiatorstvo, ki ga nisem naredil, ker ne znam popravit neobvezne naloge

hvala
lp
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB
  • spremenil: DubleG ()

BaRtMaN ::

Null terminated strings.

DubleG ::

ne razumem... :)

na vsak niz charov sem dodal \0 k prvotni besedi, pa ni pomagalo. Če si slučajno to mislil.
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB

Zgodovina sprememb…

  • spremenil: DubleG ()

BaRtMaN ::

Znakovna polja so vnaprej določene dolžine, nizi v poljih pa so velikokrat krajši. Zato se zapiše \0 na koncu uporabnih znakov.

Zdaj pa poglej, če so vsi nizi tako zapisani.

DubleG ::

Pregledal vsako vrstico... Mislim, da zdaj to več ni problem.
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB

BigWhale ::

$ gdb my_program
gdb> run

Si probal?

DubleG ::

Nisem.
[New Thread 0x7ffff7052910 (LWP 9709)]
[New Thread 0x7ffff6851910 (LWP 9710)]
[New Thread 0x7ffff6050910 (LWP 9711)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff6050910 (LWP 9711)]
0x0000000000400c89 in nit4 ()
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB

BigWhale ::

Daj prevedi z -g opcijo in ko bos dobil segfault napisi bt v debuggerju, da vidis kje stvar crkne.

DubleG ::

(gdb) backtrace
#0 0x0000000000400c89 in nit4 ()
#1 0x00007ffff7bc9a04 in start_thread () from /lib/libpthread.so.0
#2 0x00007ffff793380d in clone () from /lib/libc.so.6
#3 0x0000000000000000 in ?? ()

Ne vem no, meni to ne pove nič. Celotno funkcijo nit4 sem pregledal v detajle...
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB

Zgodovina sprememb…

  • spremenil: DubleG ()

BlueRunner ::

Tc, tc, tc...

shmid=shmget(100,sizeof(skupna_struktura*),IPC_CREAT | 0600);


Kakšna je razlika med sizeof(struct skupna_sktruktura) in sizeof(struct skupna_struktura*)?!?!?!

BlueRunner ::

Druga napaka pa je ta, da kličeš shmdt takoj po pthread_create.

Tretja napaka pa je ta, da najprej (še enkrat) kličeš shmdt + shmctl še preden si počakal, da se niti zaključijo s pthread_join. Samo zato, ker si jim poslal signal, to še ne pomeni, da so že zaključile s pisanjem po shm.

Ko boš popravil vse tri napake, lahko pobrišeš tiste '\0', ker ne služijo ničemer.

Zgodovina sprememb…

DubleG ::

HVALA!
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB

Zgodovina sprememb…

  • spremenil: DubleG ()

Ktj ::

Meni gcc in VS pravi da je sizeof(skupna_struktura): 21.

BigWhale ::

Meni gcc in VS pravi da je sizeof(skupna_struktura): 21.


To je prav ja. Ampak sizeof(... *) je pa 4 .. :)

BlueRunner ::

Meni gcc in VS pravi da je sizeof(skupna_struktura): 21.


To je prav ja. Ampak sizeof(... *) je pa 4 .. :)

Pri meni je pa 8 >:D

Ktj ::

A kot kaže sem odgovarjal na odgovor ki ga ni več :D.

DubleG ::

Sem potem ugotovil sam, sizeof(skupna_struktura) vrne 21... Zdaj pa ni več valgrinda.
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB

BigWhale ::

Meni gcc in VS pravi da je sizeof(skupna_struktura): 21.


To je prav ja. Ampak sizeof(... *) je pa 4 .. :)

Pri meni je pa 8 >:D



Ooooh, Mr. Big Shot! :P

BivšiUser2 ::

Če poženem kodo:
#include <stdio.h>
#include <stdlib.h>
int main()
{
	int n;
	scanf("%d",&n);
	int **p = (int **) malloc(201*sizeof(int *));
	for(int i=0;i<201;i++)
	{
		p[i]= (int *) calloc(201,sizeof(int));
	}
	for(int i=0;i<n;i++)
	{
		int y,x,a;
		scanf("%d %d %d",&x,&y,&a);
		x+=100;
		y+=100;
		for(int i=y;i<y+a;i++)
		{
			for(int j=x;i<x+a;j++)
			{
				p[i][j]++;
			}
		}
	}
	for(int k=1;k<=n;k++)
	{
		int stevec=0;
		for(int i=0;i<201;i++)
		{
			for(int j=0;j<201;j++)
			{
				if(p[i][j]==k)
					stevec++;
			}	
		}
		printf("%d\n",stevec);
	}
	return 0;
}
Dobim povsod seg. fault. (verjetno ga mešam pri calloc in malloc)
Če poženem
#include <stdio.h>

int main(){

    int n;
    scanf("%d", &n);
    
    int map[201][201];
    
    for(int i = 0; i < 201; i++){
        for(int j = 0; j < 201; j++){
            map[i][j] = 0;
        }
    }
    
    for(int i = 0; i < n; i++){
        int posY, posX, size;
        scanf("%d %d %d", &posY, &posX, &size);
        
        //sprintf("%d %d %d\n", posY+100, posX+100, size);
        
        posY += 100;
        posX += 100;
        
        for(int y = posY; y < size+posY; y++){
            for(int x = posX; x < size+posX; x++){
                                map[y][x]++;       }
        }
    }
    for(int k = 1; k <= n; k++){
        int count = 0;
        for(int i = 0; i < 201; i++){
            for(int j = 0; j < 201; j++){
                if(k == map[i][j]){
                    count++;
                }
            }   
        }   
        printf("%d\n", count);
    }
    return 0;
}
dobim seg. fault pri dveh primerih. Povečam z 201 > 400 (dobim timeout (verjetno lappy ne zmore procesirat v 1 sekundi)).
(-100,-100) je levo zgoraj, sega pa do (100,100)
Vhod:
4
-3 -2 3
-2 0 2
-3 -1 4
-1 -2 1
Izhod:
10
7
2
0
SloTech - če nisi z nami, si persona non grata.

al_z ::

Vsakemu malloc (calloc) mora slediti free pred zaključkom programa, drugače se lahko začnejo dogajati resne napake v pomnilniku. C nima garbage collector-ja!

Brane22 ::

A ne spuca OS vse ostalo od programa, ko ta zaključi ?
On a journey of life I chose a psycho path...

galu ::

@OP zakaj uporabljaš shmget ipd. funkcije, ki so namenjene deljenju pomnilnika med procesi? Ti delaš z nitmi, katerih fora je, da uporabljajo isto kopico, data in code segmente. Imajo celo dostop do sklada izven niti.

@Brane22
Ja, sprosti pomnilnik, da ga lahko uporabijo drugi procesi. Zato res ni potrebno neposredno pred zaključkom programa sprostiti pomnilnika, ker to stori OS.
Tako to gre.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[C] Sinhronizacija procesov

Oddelek: Programiranje
71035 (908) Cvenemir
»

skupni pomnilnik &#169; linux

Oddelek: Programiranje
62400 (2246) Keki
»

[C++] threading in random, dostop do rama

Oddelek: Programiranje
5883 (776) popec
»

[C] Narascajoce sortiranje linearnega seznama

Oddelek: Programiranje
71766 (1655) Jebiveter
»

C problemček

Oddelek: Programiranje
13990 (793) OwcA

Več podobnih tem