Why is Segmentation fault when using GMP? - c

I am using the GMP. My program can build successfully, But run failed. The following is error things:
a=1231231231231231
res^n != a
Segment fault
All codes in my program is:
#include <gmp.h>
#include <stdio.h>
int main()
{
mpz_t a,res;
unsigned long int n = 123;
char str1[] = "1231231231231231";
mpz_init_set_str(a, str1, 10);
gmp_printf("a=%Zd\n",a);
mpz_init(res);
if(mpz_root(res, a, n)){
printf("res^n == a\n");
}
else{
printf("res^n != a\n");
}
mpz_clears(a,res);
return 0;
}

You have to call mpz_clears() like:
mpz_clears(a,res, NULL);
Here's what the documentation says:
Function: void mpz_clears (mpz_t x, ...)
Free the space occupied by a NULL-terminated list of mpz_t variables.

Related

Allocating dinamicaly memory problems and VLA with characters

I know I should not use c and c++ at the same time.
Can someone say why the above code are working using new?
the purpose is to remove the central character of an word given by keyboard ex: "abcde" to "abde"
I was asking if the creation of VLA is correct or not... apparently it returns what I want BUT the same main code without the other functions crashes.
I searched throw internet and i discovered that i should initialize the size ('n' in my case)of the VLA's.
Code using functions and new:
#include <stdio.h>
#include <string.h>
int citirea_sirului(char *s1, char *s2)
{
int d;
printf("Cuvantul: ");
gets(s1);
d=strlen(s1);
for(int i=0;i<d;i+=1)
{
*(s2+i)=*(s1+i);
}
return d;
}
void prelucrarea_afis_siruluiC(char *b, int d, char *a){
strcpy(a,b+(d/2)+1);
strcpy(b+(d/2),"");
strcat(b,a);
puts(b);
}
int main(){
int n;
char *cuv,*ccuv;
cuv=new char[n];
ccuv=new char[n];
n=citirea_sirului(cuv,ccuv);
printf("Dimensiunea Cuvantului: %d\n",n);
printf("\nSir prelucrat: \n");
prelucrarea_afis_siruluiC(ccuv,n,cuv);
delete[] ccuv;
delete[] cuv;
return 0;
}
Code without functions:
#include <stdio.h>
#include <string.h>
int main(){
int n;
char cuv[n], ccuv[n];
printf("Cuvantul: ");
gets(cuv);
n=strlen(cuv);
printf("Dimensiunea Cuvantului: %d",n);
for(int i=0;i<n;i++)
{
ccuv[i]=cuv[i];
}
strcpy(cuv,cuv+(n/2)+1);
strcpy(ccuv+(n/2),"");
strcat(ccuv,cuv);
printf("\nCuvantul prelucrat: %s",ccuv);
return 0;
}

How to create a function from other 3 with the same signature in C

I'm working with C, and I'm trying to build a kind of "composite" function, by joining 2 functions with the same signature, and a third with almost the same signature but just one less argument. The functions should be executed in sequence, but the final function must have the same signature. You can think it as building a function with code blocks using same signature(I have it implemented in C++ with policy class, but I'm trying a C approach as the rest of the code is in C already).
I built some code very simple, just to explain my approach.
#include <stdio.h>
#include <stdlib.h>
typedef void simulFileProc(int a, int b);
typedef void simulRead(int a);
typedef struct compFunct{
simulFileProc* file1;
simulRead* read;
simulFileProc* file2;
} compFunct;
void realProc(int a, int b){
printf("call from realProc %d, %d\n",a,b);
}
void realRead(int a){
printf("call from read %d\n",a);
}
simulFileProc* join(int a, int b, compFunct* func){
void sf(int a, int b){
func->file1(a,b);
printf("intermediate line\n");
func->read(a);
func->file2(a,b);
}
return &sf;
}
int main() {
compFunct* c = malloc(sizeof(256));
c->file1 = &realProc;
c->read = &realRead;
c->file2 = &realProc;
int a=0;
int b=0;
simulFileProc* s = join(a,b,c);
s(4,3);
return 0;
}
It is working, but for some reason, just the first function print.
call from realProc 4, 3
intermediate line
If I comment the line "func->read(a);", I have a segmentation fault.
What is wrong ?? Is there a smarter way to do ?

C programming recursion question generating segfault

trying to convert any number to any base in a recursion with C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* anybase(int n, int b)
{
char * s;
int len;
if(n==0) {strcpy(s,""); return s;}
s = anybase(n/b, b);
len=strlen(s);
s[len] = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ"[n%b];
s[len+1]='\0';
printf ("%s, %d, %d\n", s, n, b);
/* return s; */
}
int main(){
char *s;
s = anybase(900000, 18);
/*printf ("%s, %d, %d\n", anybase(90000, 18), 90000, 18);*/
}
is it the recursion having a problem? not sure why one can't return a value in the function call. what would be needed to call this recursion function and return a value instead of void.
Why is it generating seg fault each time running it? Thanks!
You were pretty much there, except you never allocated any memory for the string you're trying to produce. Here's a version which (apparently) runs correctly:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* anybase(int n, int b)
{
char *s;
int len;
if(n == 0)
{
s = malloc(200);
s[0] = '\0';
}
else
{
s = anybase(n/b, b);
len=strlen(s);
s[len] = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ"[n%b];
s[len+1]='\0';
}
return s;
}
int main()
{
char *result;
result = anybase(900000, 18);
printf("%s\n", result);
free(result);
}
Note that since the buffer returned by anybase is allocated dynamically (using the malloc library function) it must be free'd after use.
As others mentioned the issue is s is just a pointer that points to no where.
But instead of allocating memory for s inside of your anybase function a better approach is to allocate the memory in the main function. This avoids possible memory leaks when calling the function multiple times.
#include <stdio.h>
#include <string.h>
void anybase(int n, int b, char* s)
{
int len;
if(n==0) {strcpy(s,""); return;}
anybase(n/b, b, s);
len=strlen(s);
s[len] = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ"[n%b];
s[len+1]='\0';
printf ("%s, %d, %d\n", s, n, b);
printf("%d\n", len +1);
return;
}
int main(){
char s[33]; /* enough for all ints with base 2 */
anybase(90000, 18, s);
return 0;
}
The string buffer can be created statically in the main function but must then be passed to each recursive function call such that it can be written in to.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 200
const char *selection = "0123456789ABCEDFGHIGKLMNOPQRSTUVWXYZ";
void anybase(int n, int b, char *s)
{
if (n) {
anybase(n / b, b, s);
strncat(&s[strlen(s)], &selection[n % b], sizeof(char));
printf("%s, %d, %d\n", s, n, b);
}
}
int main()
{
char buf[BUFFER_SIZE];
memset(buf, 0, sizeof(char) * BUFFER_SIZE);
anybase(900000, 18, buf);
printf("Ouput: %s, N: %d, B: %d\n", buf, 90000, 18);
}

Reversing the strings from command line with threads in C - segmentation fault

I am new with threads.
I am trying to make a C program that reverses the string given from the command line and create a thread that does this for each one . When I run it gives me Segmentation fault .
Here is the code:
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdlib.h>
#include <fcntl.h>
char* final[1000];
pthread_mutex_t *mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_t p[];
void *reverse(void* arg){
char* s[100];
char* temp;
int i;
strcpy(s,(char*)arg);
printf("S este %s",s);
for(i=0;i<=strlen(s)/2;i++){
strcpy(temp,s[i]);
strcpy(s[i],s[strlen(s)-i-1]);
strcpy(s[strlen(s)-i-1],temp);
}
sleep(1);
pthread_mutex_lock(&mutex);
strcat(final,s);
printf("Intermediar %s",s);
pthread_mutex_unlock(&mutex);
return NULL;
}
int main(int argc,char* argv[]) {
int i;
int n = argc;
strcpy(final,"");
for(i=1;i<n-2;i++){
pthread_create(&p[i],NULL,reverse,argv[i]);
}
for(i=1;i<n-2;i++){
pthread_join(p[i],NULL);
}
//printf("Sirul final este %s",final);
return 0;
}
Does anyone know a good site that could help me learn threads ?
Thanks !
char* final[1000];
is an array (with 1000 elements) of pointer to char, you want an array of char:
char final[1000];
the same problem with this array:
char* s[100];
temp is declared as a pointer, but you use it as an array with size 1
declare the mutex without the * ,remove the initialization and add in main:
pthread_mutex_init(&mutex, NULL);
you should also add a number to the array definition of pthread_t
You never initialize temp, so the call strcpy(temp, s[i]); causes undefined behavior.
Your treatment of s is also very confusing, the copying of arg (a string) into the memory used by s (an array of string pointers) is not valid. Just because you can cast away a warning doesn't mean you're doing something sensible.

Segmentation fault while processing argv

This procedure should convert a string that contains a set of double numbers separated by comma (e.g. 7.2,9.5,-5.515) to a vector of double type.
void ToDoubleVec(int d,const char* commaSeparated,double *result)
{
int i;
result[0]=atof(strtok(commaSeparated,","));
for(i=1;i<d;i++)
result[i]=atof(strtok(NULL,","));
}
Here is the snippet of program that calls it:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc,char** argv)
{
...
int i,dim=atoi(argv[1]);
double *lower;
lower = malloc(dim*sizeof(double));
ToDoubleVec(dim,argv[2],lower);
...
}
Debugger's output:
40 lower = malloc(dim*sizeof(double));
(gdb) s
42 ToDoubleVec(dim,argv[2],lower);
(gdb) s
ToDoubleVec (d=2, commaSeparated=0x7fffffffe9d3 "2.3,-62.1", result=0x603010) at testPSO.c:11
11 result[0]=atof(strtok(commaSeparated,","));
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff77f56bb in ?? () from /lib/x86_64-linux-gnu/libc.so.6
Why doesn't it work? I was sure that I've allocated enough memory for the array and also parameters seems to be passed correctly.
You can reduce your code to this SSCCE (Short, Self-Contained, Correct Example), which crashes nicely when you leave out #include <string.h> and does not compile cleanly when you add #include <string.h>:
segv.c: In function ‘ToDoubleVec’:
segv.c:8:5: warning: implicit declaration of function ‘strtok’ [-Wimplicit-function-declaration]
segv.c:8:20: warning: initialization makes pointer from integer without a cast [enabled by default]
segv.c:14:20: warning: assignment makes pointer from integer without a cast [enabled by default]
Code:
#include <stdlib.h>
//#include <string.h>
static void ToDoubleVec(int d, const char* commaSeparated, double *result)
{
int i;
result[0] = atof(strtok(commaSeparated, ","));
for (i = 1; i < d; i++)
result[i] = atof(strtok(NULL, ","));
}
int main(void)
{
int dim = 2;
double *lower = malloc(dim*sizeof(double));
char arg[] = "7.2,9.5,-5.515";
ToDoubleVec(dim, arg, lower);
}
Passing the return value from a function such as strtok() which can return a null pointer directly to a function such as atof() which does not tolerate null pointers is foolhardy; it leads to crashes. If everything is correct, you'll be OK; if not, you'll crash and burn.
The unchecked memory allocation is a similar problem; you didn't even check that dim was non-zero (and non-negative) before doing the memory allocation in the original.
#include <assert.h>
#include <string.h>
#include <stdlib.h>
static void ToDoubleVec(int d, char *commaSeparated, double *result)
{
int i;
char *number = strtok(commaSeparated, ",");
if (number != 0)
{
result[0] = atof(number);
for (i = 1; i < d; i++)
{
number = strtok(NULL, ",");
if (number != 0)
result[i] = atof(number);
}
}
}
int main(void)
{
int dim = 2;
double *lower = malloc(dim*sizeof(double));
char arg[] = "7.2,9.5,-5.515";
assert(lower != 0);
ToDoubleVec(dim, arg, lower);
}
You could — and in one version of the code I did — add error printing to report if the tests on number failed. But the crash is caused by the implicit declaration of strtok() as returning int and not char *.
I have tried to compile your code, and the compiler warned me that strtok() takes as input a char* and not a const char*. Then I have tried this code, and it is working correctly:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void ToDoubleVec(int d, char* commaSeparated,double *result);
int main(int argc,char** argv)
{
int i,dim=atoi(argv[1]);
double *lower;
lower = malloc(dim*sizeof(double));
ToDoubleVec(dim,argv[2],lower);
for (i=0; i<dim; ++i) {
printf("%f\n", lower[i]);
}
return 0;
}
void ToDoubleVec(int d, char* commaSeparated,double *result)
{
int i;
result[0]=atof(strtok(commaSeparated,","));
for(i=1;i<d;i++)
result[i]=atof(strtok(NULL,","));
}
So try to change const char* to char*, and check the input you pass to your program, maybe it is not correct and this could be the problem.

Resources