Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

quanganhct

macrumors member
Original poster
Dec 29, 2010
31
0
Hi all,
I have this error when running my program, and when i run it in Terminal, it's "Segmentation fault", so i guess that there 're some error happened when allocating memory.

here is my program
Code:
#include <iostream>
#include <cstdlib>
using namespace std;
typedef int* tabnum[1000];
void nombre2tableau (int nombre, int* tableau, int &taille){
	int i=0;
	while (nombre > 0){
		*(tableau + i)=(nombre % 10);
		nombre=nombre/10;
		i++;	
	}
	taille=i;
}

int tableau2nombre (int* tab, int taille){
	int nombre=0;
	for(int i=taille-1;i>=0;i--){
		nombre=nombre*10+ *(tab+i);
	}
	return nombre;
}

int add(int m,int n,int &cpt){
	int result;
	if(m+n+cpt >= 10){
		result=(m+n+cpt)%10;
		cpt=1;
	}
	else {
		result=m+n+cpt;
		cpt=0;
	}
	return result;
}

int subtract(int m,int n,int &cpt){
	int result;
	if(m<(n+cpt)) {
		result=m+10-n-cpt;
		cpt=1;
	}
	else{
		result=m-n-cpt;
		cpt=0;
	}
	return result;
}

int multi(int m,int n,int &cpt){
	int result;
	result=(m*n+cpt)%10;
	cpt=(m*n+cpt)/10;
	return result;
}	

void addDeuxTab (int* tab1,int taille1,int* tab2,int taille2,int* tab,int &taille){
	int min;
	int indice=2;
	int cpt=0;
	if(taille1>taille2) {
		taille=taille1;
		indice=1;
	}
	else taille=taille2;
	min=taille1+taille2-taille;
	for(int i=0;i<taille;i++){
		if(i<min) {
			*(tab+i)=add(*(tab1+i),*(tab2+i),cpt);	
		}		
		else if(indice==1) *(tab+i)=add(*(tab1+i),0,cpt);
		else *(tab+i)=add(*(tab2+i),0,cpt);
	}	
	if(cpt==1){
		taille++;
		*(tab+taille-1)=cpt;
	}
}

void sousDeuxTab(int* tab1,int taille1,int* tab2,int taille2,int* tab,int &taille){
	int min;
	int indice=2;
	int cpt=0;
	if (tableau2nombre(tab1,taille1)>tableau2nombre(tab2,taille2)) {
		indice=1;
		taille=taille1;
	}
	else taille=taille2;
	min=taille1+taille2-taille;
	for(int i=0;i<taille;i++){
		if(indice==1){
			if(i<min) {
				*(tab+i)=subtract(*(tab1+i),*(tab2+i),cpt);	
			}
			else *(tab+i)=subtract(*(tab1+i),0,cpt);		
		}
		else{
			if(i<min) {
				*(tab+i)=subtract(*(tab2+i),*(tab1+i),cpt);	
			}		
			else *(tab+i)=subtract(*(tab2+i),0,cpt);	
		}
	}
	if(indice==2) *(tab+taille-1)=-*(tab+taille-1);
}

void mulDeuxTab(int* tab1,int taille1,int* tab2,int taille2,int* tab,int &taille){
	int **tabTempt=new int* [1000];
	*tabTempt=new int [1000];
	int* tailleTab=new int[1000];
	int cpt=0;
	for(int j=0;j<taille2;j++){
		for(int i=0;i<taille1;i++){	
			*(*(tabTempt+j)+i+j)=multi(*(tab1+i),*(tab2+j),cpt);
		}	
		
		for(int k=0;k<j;k++){
			*(*(tabTempt+j)+k)=0;
		}
		if (cpt>0) {
			*(*(tabTempt+j)+taille1+j)=cpt;
			*(tailleTab+j)=taille1+1+j;
		}
		else *(tailleTab+j)=taille1+j;
	}
	addDeuxTab(*(tabTempt),*(tailleTab),*(tabTempt+1),*(tailleTab+1),tab,taille);
	
	for(int j=2;j<taille2;j++){
		addDeuxTab(*(tabTempt+j),*(tailleTab+j),tab,taille,tab,taille);
	}
	
	delete tabTempt;
	delete tailleTab;
}			  			  			  

void saisirTab (int* tab, int taille){
	for(int i=0;i<taille;i++){
		cout<<"tableau["<<i<<"] = ";
		cin>>*(tab+i);
	}
}

void afficher (int* tableau, int taille){
	for(int i=0;i<taille;i++){
		cout<<*(tableau+i)<<" ";
	}
	cout<<endl;
}

int main(){
	int nombre, taille, taille1, taille2;
	int* tableau=new int[1000];
	int* tab1=new int[1000];
	int* tab2=new int[1000];
	
	//question 1
	/*	
	 cout<<"Saisir un nombre :";
	 cin>>nombre;
	 nombre2tableau(nombre,tableau,taille);
	 cout<<"La tableau :"<<endl;
	 afficher (tableau, taille);
	 */
	
	//question 2
	/*
	 cout<<"Saisir la taille d'une tableau : ";
	 cin>>taille;
	 cout<<"Saisir une tableau :"<<endl;
	 saisirTab(tableau,taille);
	 cout<<"Nombre obtenu : "<<tableau2nombre(tableau,taille)<<endl;
	 */
	
	//question 3
	/*
	 cout<<"Saisir la taille de premiere tableau : ";
	 cin>>taille1;
	 cout<<"Saisir la premiere tableau :"<<endl;
	 saisirTab(tab1,taille1);
	 cout<<"Saisir la taille de second tableau : ";
	 cin>>taille2;
	 cout<<"Saisir la second tableau :"<<endl;
	 saisirTab(tab2,taille2);
	 addDeuxTab(tab1,taille1,tab2,taille2,tableau,taille);
	 cout<<"La tableau obtenue :"<<endl;
	 afficher(tableau,taille);
	 */
	
	//question 4
	/*
	 cout<<"Saisir la taille de premiere tableau : ";
	 cin>>taille1;
	 cout<<"Saisir la premiere tableau :"<<endl;
	 saisirTab(tab1,taille1);
	 cout<<"Saisir la taille de second tableau : ";
	 cin>>taille2;
	 cout<<"Saisir la second tableau :"<<endl;
	 saisirTab(tab2,taille2);
	 sousDeuxTab(tab1,taille1,tab2,taille2,tableau,taille);
	 cout<<"La tableau obtenue :"<<endl;
	 afficher(tableau,taille);
	 */
	
	//question 5
	
	cout<<"Saisir la taille de premiere tableau : ";
	cin>>taille1;
	cout<<"Saisir la premiere tableau :"<<endl;
	saisirTab(tab1,taille1);
	cout<<"Saisir la taille de second tableau : ";
	cin>>taille2;
	cout<<"Saisir la second tableau :"<<endl;
	saisirTab(tab2,taille2);
	mulDeuxTab(tab1,taille1,tab2,taille2,tableau,taille);
	cout<<"La tableau obtenue :"<<endl;
	afficher(tableau,taille);
	
	delete tab1;
	delete tab2;
	delete tableau;
	
	return 0;	
}

All function work well except "mulDeuxTab" (when i debug, there's an error at ligne :
*(*(tabTempt+j)+i+j)=multi(*(tab1+i),*(tab2+j),cpt);
And I really don't see what could be wrong here

Would you please help me ? Thanks in advance :p
 
Run it in XCode under the debugger instead.

Then look at the values of the various variables.

And could you please please please use write
Code:
tab [i]
instead of
Code:
* (tab + i)

That code you write just hurts my brain.
 
On top of not knowing the language used in the code (the human language, not the programming language), it was also eye-bleedingly bad use of the unary * operator, as gnasher729 pointed out.

The immediately obvious error can be corrected by changing the first few lines of mulDeuxTab to:
Code:
void mulDeuxTab(int* tab1,int taille1,int* tab2,int taille2,int* tab,int &taille){
        int **tabTempt=new int* [1000];
        //*tabTempt=new int [1000];
        int* tailleTab=new int[1000];
        for(int pos=0;pos<1000;pos++) {
                tabTempt[pos] = new int[1000];
        }

As the code was before, the first position in tabTempt was set to some new memory, but every subsequent position was not initialized, so it was garbage or null (not sure if new initializes to 0 in C++, not a C++ expert). So when j was 1 in the devil statement things were crashing on, there was an attempt to treat 0 as a pointer and dereference it, causing the crash.

I don't know if the output was right, but after my change i ran:
Code:
$ ./s
Saisir la taille de premiere tableau : 3
Saisir la premiere tableau :
tableau[0] = 4
tableau[1] = 2
tableau[2] = 5
Saisir la taille de second tableau : 3
Saisir la second tableau :
tableau[0] = 8
tableau[1] = 5
tableau[2] = 3
La tableau obtenue :
2 3 8 7 8 1

I haven't worked out the program logic, so i don't know what the intention is, and if this is the proper output, but it's better than a crash (i suppose).

There are PLENTY of other things going on here. For example, i could say i want to enter 1002 values and overflow tab1 and tab2. new is being used, so it seems somewhat trivial to build the table after the number of values is entered with the number the user wishes to enter. Alternately (or additionally) you could check to make sure they want to enter something sane before continuing.

-Lee

Oops... You'll need another loop deleting all of those, too.
At the end of mulDeuxTab:
Code:
        for(int pos=0;pos<1000;pos++) {
                delete tabTempt[pos];
        }
        delete tabTempt;
        delete tailleTab;
}

Edit 2:
While i still have no idea what this program does, i tried to rework it a bit to make more sense, have a little bounds checking, use [] in place of unary *,etc.:
Code:
#include <iostream>
#include <cstdlib>
using namespace std;

int add(int m,int n,int &cpt){
	int result;
	if(m+n+cpt >= 10){
		result=(m+n+cpt)%10;
		cpt=1;
	}
	else {
		result=m+n+cpt;
		cpt=0;
	}
	return result;
}

int multi(int m,int n,int &cpt){
	int result;
	result=(m*n+cpt)%10;
	cpt=(m*n+cpt)/10;
	return result;
}	

void addDeuxTab (int* tab1,int taille1,int* tab2,int taille2,int* tab,int &taille){
	int min;
	int cpt=0;
	int indice = 0;
	if(taille1>taille2) {
		taille=taille1;
		indice=1;
		min = taille2;
	} else {
		taille=taille2;
		indice=2;
		min = taille1;
	}
	for(int i=0;i<taille;i++){
		if(i<min) {
			tab[i]=add(tab1[i],tab2[i],cpt);	
		} else if(indice==1) {
			tab[i]=add(tab1[i],0,cpt);
		} else {
			tab[i]=add(tab2[i],0,cpt);
		}
	}	
	if(cpt==1){
		taille++;
		tab[taille-1]=cpt;
	}
}

void mulDeuxTab(int* tab1,int taille1,int* tab2,int taille2,int* tab,int &taille){
	int **tabTempt=new int* [taille2];
	int *tailleTab=new int[taille2];
	for(int pos=0;pos<taille2;pos++) {
		tabTempt[pos] = new int[taille1+taille2+1];
	}
	int cpt=0;
	for(int j=0;j<taille2;j++){
		for(int i=0;i<taille1;i++){	
			tabTempt[j][i+j]=multi(tab1[i],tab2[j],cpt);
		}	
		
		for(int k=0;k<j;k++){
			tabTempt[j][k]=0;
		}

		if (cpt>0) {
			tabTempt[j][taille1+j]=cpt;
			tailleTab[j]=taille1+1+j;
		} else {
			tailleTab[j]=taille1+j;
		}
	}
	addDeuxTab(tabTempt[0],tailleTab[0],tabTempt[1],tailleTab[1],tab,taille);
	
	for(int j=2;j<taille2;j++){
		addDeuxTab(tabTempt[j],tailleTab[j],tab,taille,tab,taille);
	}
	
	for(int pos=0;pos<taille2;pos++) {
		delete tabTempt[pos];
	}
	delete tabTempt;
	delete tailleTab;
}			  			  			  

void saisirTab (int* tab, int taille){
	for(int i=0;i<taille;i++){
		cout<<"tableau["<<i<<"] = ";
		cin>>tab[i];
	}
}

void afficher (int* tableau, int taille){
	for(int i=0;i<taille;i++){
		cout<<tableau[i]<<" ";
	}
	cout<<endl;
}

bool validateTaille(int tailleToValidate) {
	if(tailleToValidate < 1 || tailleToValidate > 1000) {
		cout << "Invalid taille entered!" << endl;
		return false;
	} else {
		return true;
	}
}

int main(){
	int nombre, taille, taille1, taille2;
	int* tableau = NULL;
	int* tab1 = NULL;
	int* tab2 = NULL;
	
	cout<<"Saisir la taille de premiere tableau : ";
	cin>>taille1;
	if(!validateTaille(taille1)) return -1;
	tab1 = new int[taille1];
	cout<<"Saisir la premiere tableau :"<<endl;
	saisirTab(tab1,taille1);
	cout<<"Saisir la taille de second tableau : ";
	cin>>taille2;
	if(!validateTaille(taille2)) return -2;
	tab2 = new int[taille2];
	cout<<"Saisir la second tableau :"<<endl;
	saisirTab(tab2,taille2);
	tableau = new int[taille1+taille2+2];
	taille=0;
	mulDeuxTab(tab1,taille1,tab2,taille2,tableau,taille);
	cout<<"La tableau obtenue :"<<endl;
	afficher(tableau,taille);
	
	delete tab1;
	delete tab2;
	delete tableau;
	
	return 0;	
}

The worst part was finding out what the size of tableau in main should be. I think i got it right now with taille1+taille2+2... but i would be more sure if i had some idea what was going on in the rest of the code.

Edit 3:
I hoped to be enlightened by running the code on paper. I was not. Maybe there are other bugs that hinder my understanding, or maybe this is just calculating something i don't understand.
 
Last edited:
thanks a lot, it works out :p
oh yeah, it seems that i miss something in my algorithm, that's reset cpt to 0 at each round, so may be you can not guess what my intention is.
Here is my complete code:
Code:
#include <iostream>
#include <cstdlib>
using namespace std;

void afficher (int* tableau, int taille){
	for(int i=0;i<taille;i++){
		cout<<*(tableau+i)<<" ";
	}
	cout<<endl;
}

void nombre2tableau (int nombre, int* tableau, int &taille){
	int i=0;
	while (nombre > 0){
		*(tableau + i)=(nombre % 10);
		nombre=nombre/10;
		i++;	
		}
	taille=i;
}

int tableau2nombre (int* tab, int taille){
	int nombre=0;
	for(int i=taille-1;i>=0;i--){
		nombre=nombre*10+ *(tab+i);
	}
	return nombre;
}

int add(int m,int n,int &cpt){
	int result;
	if(m+n+cpt >= 10){
		result=(m+n+cpt)%10;
		cpt=1;
	}
	else {
		result=m+n+cpt;
		cpt=0;
	}
	return result;
}

int subtract(int m,int n,int &cpt){
	int result;
	if(m<(n+cpt)) {
		result=m+10-n-cpt;
		cpt=1;
	}
	else{
		result=m-n-cpt;
		cpt=0;
	}
	return result;
}

int multi(int m,int n,int &cpt){
	int result;
	result=(m*n+cpt)%10;
	cpt=(m*n+cpt)/10;
	return result;
}	

void addDeuxTab (int* tab1,int taille1,int* tab2,int taille2,int* tab,int &taille){
	int min;
	int indice=2;
	int cpt=0;
	if(taille1>taille2) {
		taille=taille1;
		indice=1;
	}
	else taille=taille2;
	min=taille1+taille2-taille;
	for(int i=0;i<taille;i++){
		if(i<min) {
			*(tab+i)=add(*(tab1+i),*(tab2+i),cpt);	
			}		
		else if(indice==1) *(tab+i)=add(*(tab1+i),0,cpt);
		else *(tab+i)=add(*(tab2+i),0,cpt);
	}	
	if(cpt==1){
		taille++;
		*(tab+taille-1)=cpt;
	}
}

void sousDeuxTab(int* tab1,int taille1,int* tab2,int taille2,int* tab,int &taille){
	int min;
	int indice=2;
	int cpt=0;
	if (tableau2nombre(tab1,taille1)>tableau2nombre(tab2,taille2)) {
		indice=1;
		taille=taille1;
	}
	else taille=taille2;
	min=taille1+taille2-taille;
	for(int i=0;i<taille;i++){
		if(indice==1){
			if(i<min) {
				*(tab+i)=subtract(*(tab1+i),*(tab2+i),cpt);	
				}
				else *(tab+i)=subtract(*(tab1+i),0,cpt);		
		}
		else{
			if(i<min) {
				*(tab+i)=subtract(*(tab2+i),*(tab1+i),cpt);	
				}		
			else *(tab+i)=subtract(*(tab2+i),0,cpt);	
		}
	}
	if(indice==2) *(tab+taille-1)=-*(tab+taille-1);
}

void mulDeuxTab(int* tab1,int taille1,int* tab2,int taille2,int* tab,int &taille){
	int** tabTempt=new int*[1000];
	
	int* tailleTab=new int[1000];
	for(int i=0;i<1000;i++){
		*(tabTempt+i)=new int[1000];
	}
	int cpt=0;
	for(int j=0;j<taille2;j++){
		for(int i=0;i<taille1;i++){	
			*(*(tabTempt+j)+i+j)=multi(*(tab1+i),*(tab2+j),cpt);
		}	
		
		for(int k=0;k<j;k++){
			*(*(tabTempt+j)+k)=0;
		}
		if (cpt>0) {
			*(*(tabTempt+j)+taille1+j)=cpt;
			*(tailleTab+j)=taille1+1+j;
		}
		else *(tailleTab+j)=taille1+j;
		cpt=0;
		
		cout<<"tab "<<j<<" : ";
		afficher(*(tabTempt+j),*(tailleTab+j));
	}
	addDeuxTab(*(tabTempt),*(tailleTab),*(tabTempt+1),*(tailleTab+1),tab,taille);
	
	for(int j=2;j<taille2;j++){
		addDeuxTab(*(tabTempt+j),*(tailleTab+j),tab,taille,tab,taille);
	}
	for(int i=0;i<1000;i++){
		delete *(tabTempt+i);
	}
	delete [] tabTempt;
	delete tailleTab;
}			  			  			  
			  
void saisirTab (int* tab, int taille){
	for(int i=0;i<taille;i++){
		cout<<"tableau["<<i<<"] = ";
		cin>>*(tab+i);
	}
}


int main(){
	int nombre, taille, taille1, taille2;
	int* tableau=new int[1000];
	int* tab1=new int[1000];
	int* tab2=new int[1000];
	
	//question 1
	/*	
	cout<<"Saisir un nombre :";
	cin>>nombre;
	nombre2tableau(nombre,tableau,taille);
	cout<<"La tableau :"<<endl;
	afficher (tableau, taille);
	*/
	
	//question 2
	/*
	cout<<"Saisir la taille d'une tableau : ";
	cin>>taille;
	cout<<"Saisir une tableau :"<<endl;
	saisirTab(tableau,taille);
	cout<<"Nombre obtenu : "<<tableau2nombre(tableau,taille)<<endl;
	*/
	
	//question 3
	/*
	cout<<"Saisir la taille de premiere tableau : ";
	cin>>taille1;
	cout<<"Saisir la premiere tableau :"<<endl;
	saisirTab(tab1,taille1);
	cout<<"Saisir la taille de second tableau : ";
	cin>>taille2;
	cout<<"Saisir la second tableau :"<<endl;
	saisirTab(tab2,taille2);
	addDeuxTab(tab1,taille1,tab2,taille2,tableau,taille);
	cout<<"La tableau obtenue :"<<endl;
	afficher(tableau,taille);
	*/
	
	//question 4
	/*
	cout<<"Saisir la taille de premiere tableau : ";
	cin>>taille1;
	cout<<"Saisir la premiere tableau :"<<endl;
	saisirTab(tab1,taille1);
	cout<<"Saisir la taille de second tableau : ";
	cin>>taille2;
	cout<<"Saisir la second tableau :"<<endl;
	saisirTab(tab2,taille2);
	sousDeuxTab(tab1,taille1,tab2,taille2,tableau,taille);
	cout<<"La tableau obtenue :"<<endl;
	afficher(tableau,taille);
	*/
	
	//question 5
	
	cout<<"Saisir la taille de premiere tableau : ";
	cin>>taille1;
	cout<<"Saisir la premiere tableau :"<<endl;
	saisirTab(tab1,taille1);
	cout<<"Saisir la taille de second tableau : ";
	cin>>taille2;
	cout<<"Saisir la second tableau :"<<endl;
	saisirTab(tab2,taille2);
	mulDeuxTab(tab1,taille1,tab2,taille2,tableau,taille);
	cout<<"La tableau obtenue :"<<endl;
	afficher(tableau,taille);
	
	delete tab1;
	delete tab2;
	delete tableau;
	
	return 0;	
}

in your example,
tab1= 4 2 5
tab2= 8 5 3
the result is 2 9 5 7 8 1
it means that
524 * 358 = 187592

these 's a function tableau2nombre, its meaning is to transform a table to a number.
My pros said that 'cause there 's a limit for an integer, around 33 characters at most, so the intention of this program is to remove that limit

Again , thanks you alot

Happy New Year
 
thanks a lot, it works out :p
oh yeah, it seems that i miss something in my algorithm, that's reset cpt to 0 at each round, so may be you can not guess what my intention is.
Here is my complete code:
...
in your example,
tab1= 4 2 5
tab2= 8 5 3
the result is 2 9 5 7 8 1
it means that
524 * 358 = 187592

these 's a function tableau2nombre, its meaning is to transform a table to a number.
My pros said that 'cause there 's a limit for an integer, around 33 characters at most, so the intention of this program is to remove that limit

Again , thanks you alot

Happy New Year

It seemed like some sort of multiplication, but having the digits reversed, the bug, and the (spoken) language barrier threw me off.

I see your code is still littered with unary * to dereference after pointer addition, etc. Any reason for this instead of the much clearer use of []? Is this a requirement for the project?

-Lee
 
well i do not know that i could use pointer that way. Up to now, whenever i use pointer, i always do *(pointer) to take its value out. Anyway, thanks for reminding me :D
 
well i do not know that i could use pointer that way. Up to now, whenever i use pointer, i always do *(pointer) to take its value out. Anyway, thanks for reminding me :D

It makes your code very hard to read - so hard that I just refused to do it. Lee seems to be made from tougher stuff than me :D

Seriously: Compare

Code:
for (i = 0; i < 10; ++i) a [i] = b [i] * c [i];

with

Code:
for (i = 0; i < 10; ++i) * (a + i) = * (b + i) * * (c + i);

The first can be read and understood at a single glance, the second is a mess. The first one I read "take b index i, multiply by c index i, store to a index i". The second one I read: "Take the pointer a. Add i to the pointer. Remember that pointer for a while. Take the pointer b. Add i to the pointer. Read the value where the sum of b and i points to. Take the pointer c. Add i to the pointer. Read the value where the sum of c and i points to. Multiply these values. Store the result where the sum of a and i that I forgot long ago points to. "
 
It makes your code very hard to read - so hard that I just refused to do it. Lee seems to be made from tougher stuff than me :D

Seriously: Compare

Code:
for (i = 0; i < 10; ++i) a [i] = b [i] * c [i];

with

Code:
for (i = 0; i < 10; ++i) * (a + i) = * (b + i) * * (c + i);

The first can be read and understood at a single glance, the second is a mess. The first one I read "take b index i, multiply by c index i, store to a index i". The second one I read: "Take the pointer a. Add i to the pointer. Remember that pointer for a while. Take the pointer b. Add i to the pointer. Read the value where the sum of b and i points to. Take the pointer c. Add i to the pointer. Read the value where the sum of c and i points to. Multiply these values. Store the result where the sum of a and i that I forgot long ago points to. "

thanks
i 'll start using pointer from now on, it does make me feel easier than *(pointer).
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.