There are 3 files(generator.c, generator.h and main.c).
generator.c: There is only 1 function (gen fun) which is used to generate an array to store 10 random-generate numbers in generator.c.
generator.h:Declaration of generator.c.
main.c: There is only 1 function (main fun) in main.c which is used to print the number generated previously.
If generator.c is included in main.c and I compile it directly by execute "gcc main.c". The result is ok.
But while I compile it using " gcc -c generator.h, gcc -c main.c, gcc generator.o main.o ", it reported a warning "warning: assignment makes pointer from integer without a cast" at " p = gen(arr); " sentence in main funciton. And the final result was "Segmentation fault (core dumped)". The debug information showed "Cannot access memory at address" if i try to visit the value of pointer *p(i.e. array[0]) in the while loop of main function.
//////generator.c///////
int * gen( int arr[])
{
int i = 0;
int * p = arr;
int len = 10;
srand( (unsigned)((time)(NULL)));
while (i< len)
{
*p = rand() % ( len +1) + 0;
i ++;
p++;
}
return arr;
}
//////generator.h//////
int * gen( int arr[]);
//////main.c///////
int main(void)
{
int i = 0;
int arr[10]={0};
int * p;
p = gen(arr);
while (i < 10)
{
printf("output is %d\n",*p);// Segmentation fault (core dumped)
i++;
p++;
}
return 0;
}
Based on the addition to your question, it appears you are confused about how to include generator.h and then to compile the code. First your generator.h should be:
//////generator.h//////
#ifndef GENERATOR_H
#define GENERATOR_H 1
int *gen (int arr[]);
#endif
(edit: added appropriate Header Guards to prevent multiple inclusion of generator.h)
Your generator.c would then be:
//////generator.c///////
#include <stdlib.h>
#include "generator.h"
int *gen (int arr[])
{
int i = 0;
int * p = arr;
int len = 10;
while (i< len)
{
*p = rand() % len + 1;
i ++;
p++;
}
return arr;
}
And finally your main.c (I called it gen.c) would be:
//////main.c///////
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "generator.h"
int main(void)
{
int i = 0;
int arr[10]={0};
int *p;
srand( (unsigned)((time)(NULL)));
p = gen(arr);
while (i < 10)
{
printf ("output is %d\n",*p);
i++;
p++;
}
return 0;
}
Compile
$ gcc -Wall -Wextra -pedantic -std=c11 -Ofast generator.c -o bin/gen gen.c
(note: I would also encourage adding -Wshadow as a normal part of your compile string as well to identify any shadowed variables)
Example Use/Output
$ ./bin/gen
output is 8
output is 1
output is 5
output is 4
output is 9
output is 5
output is 4
output is 6
output is 5
output is 6
Look things over and let me know if you have further questions.
Related
I am writing this piece of code which works without any errors but when I run it with valgrind it throws errors that Conditional jump or move depends on uninitialized value which is caused by the while loop trying to access the third element in the array
My question is can I use the function get_index() since it does not show any warnings or errors when compiling with gcc -g -Wall -pedantic main.c and outputs the same index as the idx which is declared globally
#include <stdio.h>
#include <stdlib.h>
#define L 3
int *ptr;
int idx=0; // index
int get_index()
{
int x=0;
while(ptr[x])
x++;
return x;
}
void add_elem()
{
printf("Enter your number :\n");
scanf("%d",&ptr[idx]);
idx++;
}
int main(void) {
ptr = (int*)malloc(sizeof(int));
add_elem();
add_elem();
printf("Current index : %d\n",get_index());
printf("Original index : %d\n",idx);
return 0;
}
I'm trying to link libraries I made to main source code, but it throws this error. I've been searching for last two hours how to fix this but nothing worked for me.
Compiling:
cd "c:\Users\miros\OneDrive\Documents\C codes\labovi"
gcc 01main.c -o 01main
.\01main
d:/programs/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\miros\AppData\Local\Temp\ccGHtHKg.o:01main.c:(.text+0x46): undefined reference to 'faktorijel'
d:/programs/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\miros\AppData\Local\Temp\ccGHtHKg.o:01main.c:(.text+0x72): undefined reference to 'suma'
collect2.exe: error: ld returned 1 exit status
01ucitavanje.h
#ifndef UCITAVANJE_H
#define UCITAVANJE_H
#include <stdio.h>
#include <stdlib.h>
long long *niz;
int n;
void ucitavanje();
#endif
01ucitavanje.c
#include "01ucitavanje.h"
void ucitavanje(){
scanf("%d", &n);
niz = malloc(sizeof(long long) * n);
for (int i = 0; i < n; i++)
scanf("%d", niz + i);
}
01izracunavanje.h
#ifndef IZRACUNAVANJE_H
#define IZRACUNAVANJE_H
#include <stdio.h>
long long faktorijel(int n);
long long suma(long long *niz, int n);
#endif
01izracunavanje.c
#include "01izracunavanje.h"
long long faktorijel(int n){
long long f;
for (int i = 2; i <= n; i++)
f *= i;
return f;
}
long long suma (long long *niz, int n){
long long s = niz[0];
for (int i = 1; i < n; i++)
s += niz[i];
return s;
}
main.c
#include "01izracunavanje.h"
#include "01ucitavanje.h"
int main(){
ucitavanje();
for (int i = 0; i < n; i++)
niz[i] = faktorijel((int)niz[i]);
printf("%d", suma(niz, n));
free(niz);
return 0;
}
You're compiling only main.c into the executable, so the other functions aren't available.
You need to compile each source file into an object file, then link the object files together.
gcc -c main.c
gcc -c 01izracunavanje.c
gcc -c 01ucitavanje.c
gcc -o 01main main.o 01izracunavanje.o 01ucitavanje.o
I'm going to give you a mid-line correction because you put your compilation on one very long line.
In this case, you pass all your .c files to gcc. From
{ gcc 01main.c -o 01main }
We'd rather write
{ gcc -o 01main 01main.c 01izracunavanje.c 01ucitavanje.c }
Since you're not actually building a distribution library but rather a bunch of source files we just compile them all together. It generates better code that way anyway once you start optimizing.
Order of .c files doesn't really matter, but the file containing main is first by tradition. Putting -o before the first .c file used to matter and most people still do it.
I'm writing a C program that reads a string in the form of a table from a .txt file, counts rows and columns in it and prints the table to a different .txt file.
Here's the input table:
Something.Something-Something
Something.Something-Something
Something.Something-Something
Something.Something-Something
Here's how I run the program:
gcc -Wall -Wextra -Werror -o main main.c
./main <tabin.txt >tabout.txt
The program itself:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define ROW_LENGTH 10240
int rowNumber(char buffer[ROW_LENGTH], int i, int rowcounter) {
if(buffer[i] == '\n')
++rowcounter;
return rowcounter;
}
int colNumber(char buffer[ROW_LENGTH], int i, int colcounter) {
if(!isalnum(buffer[i]))
++colcounter;
return colcounter;
}
int main() {
char buffer[ROW_LENGTH];
int rowcounter = 0;
int colcounter = 0;
while(fgets(buffer, ROW_LENGTH, stdin) != NULL)
for(int i = 0; buffer[i]; i++) {
rowcounter = rowNumber(buffer, i, rowcounter);
colcounter = colNumber(buffer, i, colcounter);
printf("%c", buffer[i]);
}
printf("\n%d", rowcounter);
printf("\n%d", colcounter);
return 0;
}
And know the part I don't understand. I'm using CLion on Ubuntu. When I place the cursor right after the last g and save, I get
3
11
However when place the cursor on the first character of the next line, I get
4
12
What are the ways I can change my code so cursor position doesn't influence the results I get?
package.c:
double * foo(int length) {
int i;
double * a;
a = malloc(sizeof(double) * length)
for(i = 0; i < length; i++ ) {
a[i] = 0.0;
}
return a;
}
main.c
int main(void) {
int i;
double * vector;
vector = foo(999999);
for(i =0;i < 999999; i++) {
printf("%f", vector[i]);
}
return 0
}
What's the problem with my code? I'm getting segmentation fault(core dumped), my dinamic vectors are always with more than 1m elements.
Your main file doesn't contain a declaration for foo. So the compiler assumes the declaration is int foo(), i.e. a function that takes an unknown number of arguments and returns an int.
When compiling you should have gotten a warning similar to this:
warning: implicit declaration of function ‘foo’
warning: assignment makes pointer from integer without a cast
As a result, the return value isn't being captured correctly resulting in undefined behavior, which in this case manifested in a core dump.
Add a prototype to main and that should fix the error.
double * foo(int length);
int main(void) {
...
You should also #include <stdio.h> in main.c and #include <stdlib.h> in package.c and main.c to get the prototypes of printf and malloc respectively.
Also, don't forget to free(vector) at the end of your program to clean up the allocated memory.
i have been trying for hours and it drives me crazy. The last error I get is :
demo_cblas.c:(.text+0x83): undefined reference to `clapack_sgetrf'
demo_cblas.c:(.text+0xa3): undefined reference to `clapack_sgetri'
I am compiling the code using
/usr/bin/gcc -o demo_cblas demo_cblas.c -L /usr/lib64 -l :libgfortran.so.3 -L /usr/lib64 \
-llapack -L /usr/lib64 -lblas
I try with and without libgfortran, with different compilers gcc-33, gcc-47, gcc-48. The test code is not from me but comes from this forum ...
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "clapack.h"
#include "cblas.h"
void invertMatrix(float *a, unsigned int height){
int info, ipiv[height];
info = clapack_sgetrf(CblasColMajor, height, height, a, height, ipiv);
info = clapack_sgetri(CblasColMajor, height, a, height, ipiv);
}
void displayMatrix(float *a, unsigned int height, unsigned int width)
{
int i, j;
for(i = 0; i < height; i++){
for(j = 0; j < width; j++)
{
printf("%1.3f ", a[height*j + i]);
}
printf("\n");
}
printf("\n");
}
int main(int argc, char *argv[])
{
int i;
float a[9], b[9], c[9];
srand(time(NULL));
for(i = 0; i < 9; i++)
{
a[i] = 1.0f*rand()/RAND_MAX;
b[i] = a[i];
}
displayMatrix(a, 3, 3);
return 0;
}
I am on Suse 12.3 64bits. In /usr/lib64 I have liblapack.a liblapack.so, ... and libblas.a libblas.so, ... and libgfortran.so.3
The same code without the function "invertMatrix" (the one using the library) compiles fine.
Any idea or suggestion ?
Thank you all for your help.
Vava
I'm quite positive that you also need to link to libcblas, which is the c wrapper library for libblas. Note that libblas is a FORTRAN library which therefore does not contain the function clapack_* you're calling.
I've just got this working on FreeBSD with:
gcc -o test test.c \
-llapack -lblas -lalapack -lcblas
I'd installed math/atlas (from ports) and the lapack and blas packages.
See my question here