Indexing function for dynamic arrays in c - c

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;
}

Related

C program giving incorrect output

I am writing a C program to sum up prime numbers below a certain limit (9 for now). I expect 17 but the compiler gave me an unexpected output of 32781.
#include <stdio.h>
#include <stdbool.h>
bool isprime(int n);
int main(){
const int LIMIT=9;
int sum;
for (int j=1;j<LIMIT;j++){
if (isprime(j)){
sum+=j;
}
}
printf("%d",sum);
return 0;
}
bool isprime(int n){
if (n<=1){
return false;
}
else{
for(int i=2;i<n;i++){
if (n%i==0){
return false;
break;
}
}
return true;
}
}
Does anyone understand why this happened?
You declarred int sum; but didn't give sum a starting value, so it's basically reading garbage from memory. In c you need to initialize your variables properly. int sum = 0; should fix the problem.
If you are using clang as your compiler, compiling using -Wall should warn you about this.
Local variables are not initialized, so you need to initialize at declaration or before use.
int sum = 0;
or...
int sum;
for (sum = 0; bla; bla)
If the variable had been declared globally (outside of any function... main is a function) it will automatically initialize to 0.
#include <stdio.h>
int a;
int main(void)
{
int b;
printf("%d\n%d\n", a, b);
return 0;
}
Variable 'a' will be 0 and 'b' will be garbage because it's an uninitialized local variable.

C - Cursor placement influencing program

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?

multifile direct compile ok, direct compile error

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.

Strange error (the program works right only if i print)

#include <stdio.h>
#include <stdlib.h>
int factor(int n, int k, int v[], int *check){
int i=0;
if (n==1) {
*check=1;
return 1;
}
while (i<k && *check!=1){
if (n%v[i]==0) factor(n/v[i], k, v, check);
i++;
}
if (*check==1) return 1;
else return 0;
}
int fac(int n, int k, int v[]){
int check;
return factor(n,k,v,&check);
}
int main(){
int i,k, temp;
int P[2]={2,3};
int A[100];
for (i=1; i<20;i++) A[i]=0;
for (i=1; i<20;i++) {
temp=fac(i,2,P);
if(temp==1) {/*printf("%d ", temp);*/ A[i]=6; }
}
printf("\n");
for (i=1; i<20;i++) printf("%d ", A[i]);
return 1;
}
This function finds the integers <20 that can be expressed as the product of 2 and 3. Factor and fac check if the number can be expressed in that way; in the main i create a vector A in this way: A[i]=0 if i cannot be expressed in that way, A[i]=6 otherwise. The problem is that if i use the commented line the program works right, but if i don't use it, A will be made of only 6s. How is that possible (i think it's corrleated with the pointer argument in factor function, but i'm not sure)?
Problems like this usually mean that there is undefined behaviour somewhere. In order to spot the problem early, always compile with warnings enabled; e.g. if you use GCC, always provide at least -Wall flag (and -O3 often helps to get more warnings, since compiler analyzes the code more thoroughly).
E.g. this is the output when I compile your code:
gcc -Wall -O3 my.c
my.c: In function ‘fac’:
my.c:19:7: warning: ‘check’ may be used uninitialized in this function [-Wmaybe-uninitialized]
int check;
^
So, as it points out, the variable check is left uninitialized. I'm afraid that your intention was to always initialize it with this snippet:
if (n==1) {
*check=1;
return 1;
}
But it doesn't work this way: the next time fac is called, there is a new local variable check, and it's left uninitialized.
I'm not sure the logic in your code is correct, but fixing this undefined behaviour should eliminate the "strange" error which you observe.

Segmentation fault (core dumped), working with dynamic vectors

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.

Resources