What's wrong in this C program..? - c

struct bucket
{
int nStrings; //No. of Strings in a Bucket.
char strings[MAXSTRINGS][MAXWORDLENGTH]; // A bucket row can contain maximum 9 strings of max string length 10.
};//buck[TOTBUCKETS];
void lexSorting(char array[][10], int lenArray, int symb) //symb - symbol, sorting based on character symbols.
{
int i, j;
int bucketNo;
int tBuckNStrings;
bucket buck[TOTBUCKETS];
for(i=0; i<lenArray; i++)
{
bucketNo = array[i][symb] - 'a'; // Find Bucket No. in which the string is to be placed.
tBuckNStrings = buck[bucketNo].nStrings; // temp variable for storing nStrings var in bucket structure.
strcpy(buck[bucketNo].strings[tBuckNStrings],array[i]); // Store the string in its bucket.
buck[bucketNo].nStrings = ++tBuckNStrings; //Increment the nStrings value of the bucket.
}
// lexSorting(array, lenArray, ++symb);
printf("****** %d ******\n", symb);
for(i=0; i<TOTBUCKETS; i++)
{
printf("%c = ", i+'a');
for(j=0; j<buck[i].nStrings; j++)
printf("%s ",buck[i].strings[j]);
printf("\n");
}
}
int main()
{
char array[][10] = {"able","aback","a","abet","acid","yawn","yard","yarn","year","yoke"};
int lenArray = 10;
int i;
printf("Strings: ");
for(i=0; i<lenArray; i++)
printf("%s ",array[i]);
printf("\n");
lexSorting(array, lenArray, 0);
}
Well here is the complete code, that I am trying. since its been a long time since i have touched upon C programming, so somewhere i am making mistake in structure declaration.
The problem goes here:-
1) I have declared a structure above and its object as array(buck[]).
2) Now when I declare this object array along with the structure, it works fine.. I have commented this thing right now.
3) But when I declare this object array inside the function.. because ultimately i have to declare inside function( as i need to build a recursive program, where objects will be created in very recursive call) then the program is throwing segmentation fault.
Expected Output
> [others#centos htdocs]$ ./a.out
> Strings: able aback a abet acid yawn
> yard yarn year yoke
> ****** 0 ******
> a = able aback a abet acid
> b =
> c
> .
> .
> y = yawn yard yarnyear yoke
> z =
Actual Output
[others#centos htdocs]$ ./a.out
Strings: able aback a abet acid yawn yard yarn year yoke
Segmentation fault
I have no idea, what difference I made in this. Kindly help.
Thanks.

What's wrong with your program is that it doesn't contain a main() function hence it won't link.
Beyond that, you should always do the following when asking questions here:
Provide a complete, minimal code sample that demonstrates the problem.
Detail the expected behaviour.
Detail the actual behaviour.
In fact, when I add the line:
int main (void) { return 0; }
it compiles and links fine.
That means it's almost certainly a run-time error you're experiencing hence we need the main() to figure out what you're doing wrong.
Using my psychic debugging skills, an important difference between declaring it at file scope and block scope is that the file-scope version will be initialised to zeros.
That means all the structure fields will be effectively zero (for the count) and empty strings (for the strings). With block scope, those counts and strings will be uninitialised.
The fact that you're using TOBUCKETS to print the structure out probably means you're trying to print out one of those uninitialised strings.
I think what's probably happening is that the nStrings field contains a garbage value when you start the processing. You should probably initialise it to zero manually (with a loop) and see if that fixes your problem. Put this after the declaration of buck in your sort function:
for (i = 0; i < TOTBUCKETS; i++)
buck[i].nStrings = 0;
Right. It turns out that was the problem. When I fix up the errors in your latest code, I get the segmentation violation as well but, when I add that section above, it works fine:
#include <stdio.h>
#include <string.h>
#define MAXSTRINGS 9
#define MAXWORDLENGTH 10
#define TOTBUCKETS 26
struct bucket
{
int nStrings;
char strings[MAXSTRINGS][MAXWORDLENGTH];
};
void lexSorting(char array[][10], int lenArray, int symb)
{
int i, j;
int bucketNo;
int tBuckNStrings;
struct bucket buck[TOTBUCKETS];
for(i=0; i<TOTBUCKETS; i++) buck[i].nStrings = 0;
for(i=0; i<lenArray; i++)
{
bucketNo = array[i][symb] - 'a';
tBuckNStrings = buck[bucketNo].nStrings;
strcpy(buck[bucketNo].strings[tBuckNStrings],array[i]);
buck[bucketNo].nStrings = ++tBuckNStrings;
}
printf("****** %d ******\n", symb);
for(i=0; i<TOTBUCKETS; i++)
{
printf("%c = ", i+'a');
for(j=0; j<buck[i].nStrings; j++)
printf("%s ",buck[i].strings[j]);
printf("\n");
}
}
int main()
{
char array[][10] = {"able","aback","a","abet","acid",
"yawn","yard","yarn","year","yoke"};
int lenArray = 10;
int i;
printf("Strings: ");
for(i=0; i<lenArray; i++)
printf("%s ",array[i]);
printf("\n");
lexSorting(array, lenArray, 0);
}
The output of that was:
Strings: able aback a abet acid yawn yard yarn year yoke
****** 0 ******
a = able aback a abet acid
b =
c =
d =
e =
f =
g =
h =
i =
j =
k =
l =
m =
n =
o =
p =
q =
r =
s =
t =
u =
v =
w =
x =
y = yawn yard yarn year yoke
z =

keyword struct is not required when you create objects for it.

Related

Segmentation fault with concatenation of two strings

I'm trying to build alphanumeric strings consisting of 3 initial letters and 3 final numbers and save them in a .txt file. I wrote this:
int i = 0,
j = 0;
char name_cpu[8],
array_numbers_final[8],
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
The problem is that at the first external for loop it correctly prints a string of the form "AAA000". At the second for loop it goes in segmentation fault. Can anyone tell me what and where I am doing wrong?
EDIT:
A minimal reproducible example is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void){
FILE *list_cpu = NULL;
int i = 0,
number_cpu = 3,
j = 0;
char name_cpu[8] = {0},
array_numbers_final[8] = {0},
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
list_cpu = fopen("list_cpu.txt", "w");
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
fclose(list_cpu);
return(0);
}
If number_cpu is equal to 1 it works. But if it is higher then 1, the program goes into segmentation fault.
answer to new edits to OP
Edits to OP include initialization of variables addressing some instances of undefined behavior in original code, however buffer overflow problem remains in following section:
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
fclose(list_cpu);
Where name_cpu is defined with 8 char: char name_cpu[8] = {0}
"If number_cpu is equal to 1 it works. But if it is higher then 1, the program goes into segmentation fault."...
After first iteration of outer loop, including one strcat of name_cpu and list_cpu, the char name_cpu is populated with 6 new characters and \0 in remaining locations. Eg:
//example
|S|J|P|Y|E|P|\0|\0| //
The error occurs at end of 2nd iteration of outer loop at the strcat() statement. The inner loop re-populated the first three positions of name_cpu, eg:
//first three positions changed, the rest remains
|C|B|A|Y|E|P|\0|\0| //
^ ^ ^ updated values
Error occurs when the new value for array_numbers_final :
|G|H|O|\0|\0|\0|\0|\0|
is attempted to be concatenated to name_cpu, resulting in:
|C|B|A|Y|E|P|G|H|O| //attempt to write to memory not owned
^end of buffer
Resulting in buffer overflow error, and likely the segmentation fault error condition.
Again, as before, design variables to meet the potential needs of of the program. In this instance the following will work:
char name_cpu[100] = {0};
char array_numbers_final[100] = {0};
answer to original post:
The problem is here:
strcat(name_cpu, array_numbers_final);//undefined behavior.
First, name_cpu[8] is uninitialized at time of declaration, nor is it initialized at any time before used. Because it is not guaranteed what the contents are, it is not necessarily a string. Using this variable as is in any string function can invoke undefined behavior
Furthermore,(even if name_cpu is a valid string) when array_numbers_final is concatenated to name_cpu, the buffer will overflow. During my test run I saw this:
The fix is to start off with initialized buffers of sufficient size for intended purpose. eg:
char name_cpu[100] = {0}
array_numbers_final[100] = {0},
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
Code example below is adaptation using your provided example, with suggested edits. Read in-line comments:
int main(void)
{
int number_cpu = 3;//added - previously not defined in OP
int i = 0,
j = 0;
char name_cpu[100] = {0},//resized and initialize
array_numbers_final[100] = {0},//resized and initialize
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(stdout, "%s \n", name_cpu);//to stdout
// ^ changed here
}
return 0;
}

TF Lite C API crashes on second iteration

I am trying to use the C API of TF Lite to execute the inference cyclically, e.g. I set up the interpreter and feed him inputs every second or so to get predictions.
For this purpose, I have built libtensorflowlite_c.so via bazel. As documented here, I try to do the inference like this, but inside a for loop to simulate the cyclic execution:
#include "tensorflow/lite/c/c_api.h"
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char* argv[]) {
for(int i = 0; i < 3; i++)
{
printf("Iteration: %d\n", i);
float input[49] = { 0.0 };
TfLiteModel* model = TfLiteModelCreateFromFile("model.tflite");
TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate();
TfLiteInterpreterOptionsSetNumThreads(options, 2);
TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options);
TfLiteInterpreterAllocateTensors(interpreter);
TfLiteTensor* input_tensor = TfLiteInterpreterGetInputTensor(interpreter, 0);
TfLiteTensorCopyFromBuffer(input_tensor, input, 49 * sizeof(float));
TfLiteInterpreterInvoke(interpreter);
const TfLiteTensor* output_tensor = TfLiteInterpreterGetOutputTensor(interpreter, 14);
float output[49];
TfLiteTensorCopyToBuffer(output_tensor, output, 49 * sizeof(float));
printf("Output: \n\n");
for (int j = 0; j < 49; j++) {
printf("%d: %f\n", j, output[j]);
}
TfLiteInterpreterDelete(interpreter);
TfLiteInterpreterOptionsDelete(options);
TfLiteModelDelete(model);
}
return 0;
}
The first iteration runs fine and returns something. But on the second iteration, I get a SegFault when calling TfLiteTensorCopyToBuffer(output_tensor, output, 49 * sizeof(float));. Reason for this is that the previous function TfLiteInterpreterGetOutputTensor returns a nullpointer.
I expected to run this multiple times without any problems, as I destroy all old instances of variables at the end of the for-loop and thus start a fresh interpreter everytime. Obviously, this is not the case.
Can somebody provide any guidance on this? Also, I know that I probably do not have to create an interpreter on every iteration, but I wanted to make sure that everything is created new when I start over again.
EDIT:
I tried rewriting the code to exclude unnecessary parts from the actual loop:
#include "tensorflow/lite/c/c_api.h"
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char* argv[]) {
float input[49] = {0.0};
float output[49] = {[0 ... 48] = 2.5};
TfLiteModel* model = TfLiteModelCreateFromFile("VariationalAutoencoder_440.tflite");
TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate();
TfLiteInterpreterOptionsSetNumThreads(options, 2);
TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options);
TfLiteInterpreterAllocateTensors(interpreter);
TfLiteTensor* input_tensor = TfLiteInterpreterGetInputTensor(interpreter, 0);
const TfLiteTensor* output_tensor = TfLiteInterpreterGetOutputTensor(interpreter, 14);
for(int i = 0; i < 3; i++)
{
printf("\nIteration: %d\n", i);
TfLiteTensorCopyFromBuffer(input_tensor, input, 49 * sizeof(float));
TfLiteInterpreterInvoke(interpreter);
TfLiteTensorCopyToBuffer(output_tensor, output, 49 * sizeof(float));
printf("Output: \n");
for (int j = 0; j < 49; j++)
{
printf("%02d: %f\n", j, output[j]);
}
}
TfLiteInterpreterDelete(interpreter);
TfLiteInterpreterOptionsDelete(options);
TfLiteModelDelete(model);
return 0;
}
Remove all variable declarations outside and prior to the for loop, eg:
int main (int argc, char* argv[]) {
float input[49] = { 0.0 };
float output[49] = {0.0};//also needs to be initialized
//and others...
for(int i = 0; i < 3; i++)
{
printf("Iteration: %d\n", i);
....
Do the same for any calls that are creating re-usable objects, or allocating memory. Re-declaring re-usable objects in a loop (without freeing them before re-declare) can have similar results to calling malloc in a loop rather than using realloc for subsequent calls.
Your code snippet shows that you have created and deleted the following inside the loop:
TfLiteInterpreterDelete(interpreter);
TfLiteInterpreterOptionsDelete(options);
TfLiteModelDelete(model);
Calling this in a loop may also be problematic.
TfLiteTensor* input_tensor = TfLiteInterpreterGetInputTensor(interpreter, 0);
input_tensor, I believe should be created once, then, in the loop, resized as needed.
From the link you provide:
// NOTE: After a resize, the client *must* explicitly allocate tensors before
// attempting to access the resized tensor data or invoke the interpreter.
// REQUIRES: 0 <= input_index < TfLiteInterpreterGetInputTensorCount(tensor)
TFL_CAPI_EXPORT extern TfLiteStatus TfLiteInterpreterResizeInputTensor(
TfLiteInterpreter* interpreter, int32_t input_index, const int* input_dims,
int32_t input_dims_size);
Edit: One other item that seems odd:
const TfLiteTensor* output_tensor = TfLiteInterpreterGetOutputTensor(interpreter, 14);
The modifier const seems an odd bedfellow to output_tensor. It would seem if this variable will change inside the loop, then it should not be modified to const.
Your code is running well if TfLiteInterpreterGetOutputTensor use index below TfLiteInterpreterGetOutputTensorCount.
Maybe the tensor index 14 should be 13, but this depends on your model.
Adding some check like :
int count = TfLiteInterpreterGetOutputTensorCount(interpreter);
printf("output tensor count:%d\n", count);
if (count > 14) {
const TfLiteTensor* output_tensor = TfLiteInterpreterGetOutputTensor(interpreter, 14);
float output[49];
TfLiteTensorCopyToBuffer(output_tensor, output, 49 * sizeof(float));
printf("Output: \n\n");
for (int j = 0; j < 49; j++) {
printf("%d: %f\n", j, output[j]);
}
}

Everytime I declare I function, my variable made by the function changes. C Language

so I am working on my Binary adding program, but now I am stuck. I want to declare 2 variables for the first binary and second one, so I use the getBinary function I created to declare these 2. However, after I entered value for firstBin, I got the value I want, but after I entered the value for secBin, the value of firstBin somehow changes and become the same as secondBin. I was hoping for the variable to be unchangable. Thanks for the help
#include <stdio.h>
int * getBinary(){
int i;
int j;
static int first8bits[8];
for (i = 0; i != 8; i++){
printf("Input 8-bits Binary:");
scanf("%d",&first8bits[i]);
}
for (j = 0; j != 8; j++)
printf("%d",first8bits[j]);
printf("\n");
return first8bits;
}
int main(){
int o;
printf("Input the first Set of Binary...");
const int * firstBin = getBinary();
printf("Input the second Set of Binary...");
int * secBin = getBinary();
for (o = 0; o != 8; o++)
printf("%d",firstBin[o]);
}
Because of the static keyword.
Don't use static. Try:
int* first8bits = malloc(8 * sizeof(int));
This way you will allocate new memory each time you call it. You can still access it with the same [ i ] subscript. Remember to free the memory again at the end of main!
free(firstBin);
free(secBin);

Pass unknown size array of structs to functions and fill

First of, I'll admit I don't know much about C and pointers, but I've been reading up and have yet to find a solution. I have also tried some solutions found here on SO but none have worked.
The info to fill the structs, as well as the size of the array, is read from a file. So, I want to declare the array in main(), to use in further processing and pass it by reference to read_p5_info() where it is initialized and filled. 'configs' is to be filled by the configurations() function.
typedef struct pentomino_info pentomino_info;
struct pentomino_info {
char name;
int orientations;
int blocks[5][2];
int configs[8];
};
int read_p5_info(int *npieces, int *matrix_size, pentomino_info **pieces) {
// piece info is read from file
// npiece and matrix_size are also read from the file
// With file I'm testing with, npieces = 12 and matrix_size = 5
*pieces = malloc(*npieces * sizeof *pieces);
for (p = 0 ; p < *npieces ; p++) {
pieces[p] = malloc(sizeof *pieces[p]);
ret = fscanf(fp, "%c %*d %d %d %*d %*d %*f", &pieces[p]->name, &p5_rotations, &p5_flips);
pieces[p]->orientations = p5_rotations * p5_flips;
// read p5 blocks
int b = 0;
for (l = *matrix_size - 1 ; l >= 0 ; l--) {
for (c = 0 ; c < *matrix_size ; c++) {
// p5_char is a char read from the file
if(p5_char == '#' || p5_char == 'X') {
pieces[p]->blocks[b][0]=c;
pieces[p]->blocks[b][1]=l;
b++;
}
}
}
}
return 0;
}
int main() {
int npieces, matrix_size;
pentomino_info *pieces; // array of p5 pieces
int ret;
ret = read_p5_info(&npieces, &matrix_size, &pieces);
// configurations() operates on each piece individually
configurations(matrix_size, &pieces[k]);
}
The pieces I'm talking about are Pentominos. npieces is the number of pentaminos the file has information for, matrix_size is because pentamino_info.blocks has coordinates X,Y of the placement of each block in a matrix_size x matrix_size matrix.
I get segfault at the end of main(). pieces[0] seems fine but still gives me segfault, and the others are just malformed.
I tried to make the code a bit more compact by removing some parts that didn't seemed relevant, if I overdid it let me know. Thanks in advance for any help.
*pieces = malloc(*npieces * sizeof *pieces); allocates the wrong amount of memory. Should be sizeof **pieces. The pattern is P = malloc(N * sizeof *P); as a cognitive cross-check, check that there is one more star on the front of the argument to sizeof.
pieces[p]->x should be (*pieces)[p].x, you make this error in multiple places. In array notation, you wrote pieces[p][0].x but the correct indexing is pieces[0][p].x. The pointer pieces only points to one pointer, which then points to the first element of an array of infos.
If this is confusing I would recommend using "normal" pointers in your function, and then implementing the return-by-reference at the end, e.g.:
int n_pie = 12; // or whatever you read
pentomino_info *pie = malloc(n_pie * sizeof *pie);
// ...
pie[p].orientations = bla;
// ...
*npieces = n_pie;
*pieces = pie;
return 0;

array of strings printing wrong values

I trying to make a program that calculates proper prefixes and proper suffixes , and then compare the sets , and then return the array containing values representing number of matched
pairs , This could be used later in KMP algorithm .
But the problem is prefixes and suffixes array give wrong values .
Even after appending a new element at new index, it replaces the all value in the array with the new element .
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int* lps(char *,int );
int main()
{
char *pat = "abababca";
int *ptr ;
ptr = lps(pat,strlen(pat));
printf("\n***LPS***\n");
}
int * lps (char *p,int s)
{
char *prefixes[s] ;
char *suffixes[s] ;
char tmp1[s] , tmp2[s];
int i , j , k , c1 , c2 , c;
for (i = 0 ; i < s ; i ++)
{
printf("\n\n*** --- Creating Prefixes and Suffixes for i = %d --- ***",i);
c1 = 0 ;
//create prefixes
for (j = 0 ; j < i; j++)
{
for (k =0 ; k <= j; k++)
{
tmp1[k]=*(p+k);
printf("\n *(p+%d)= %c , tmp1[%d]=%c",k,*(p+k),k,tmp1[k]);
}
tmp1[k]='\0';
printf("\nprefixes[0]:%s",prefixes[0]);
prefixes[c1] = tmp1;
//strcpy(prefixes[c1], tmp1);
printf("\ncurrently added %s to prefixes at %d and prefixes[%d]= %s\n ",tmp1,c1,c1,prefixes[c1]);
c1++;
}
//print prefixes
for (k = 0; k<c1; k++)
{
printf("\tprefixes[%d] = %s",k,prefixes[k]);
}
printf("\n");
//create suffixes
c2 = 0;
for (j = 1 ; j <= i; j++)
{
for (k = j ; k <= i; k++)
{
tmp2[k-j] = *((p+k));
printf("\n *(p+%d)= %c , tmp2[%d]=%c",k,*(p+k),k-j,tmp2[k-j]);
}
tmp2[k-j]='\0';
suffixes[c2] = tmp2 ;
// strcpy(suffixes[c2], tmp2);
printf("\ncurrently added %s to suffixes at %d and suffixes[%d]= %s\n",tmp2,c2,c2,suffixes[c2]);
c2++;
}
//prinf suffixes
for (k = 0; k<c2; k++)
{
printf("\tsuffixes[%d] = %s",k,suffixes[k]);
}
printf("\n");
//compare the prefixes and suffixes
c = 0 ;
for (j = 0; j < c1; j++)
{
for(k=0 ; k < c2 ; k++)
{
printf("\nprefixes[%d] = %s , suffixes[%d] = %s\n ",j,prefixes[j],k,suffixes[k]);
if (strcmp(prefixes[j], suffixes[k])==0)
{
c = c + 1 ;
}
}
}
}
}
OUTPUT (Some part of OUTPUT) :-
prefixes[0] = ab prefixes[1] = ab //it should be prefixes[0] = a prefixes[1] = ab
The problem is that you aren't allocating any strings. The only strings that you have in lps are tmp1 and tmp2. You then make assignments like this:
prefixes[c1] = tmp1;
That assigns a pointer but does not copy the contents of the string. You'll end up with every entry in prefixes pointing to the same string, tmp1. And likewise for suffixes.
You'll need to use malloc and strcpy to make new string instances.
In the code you have commented out calls to strcpy. I suspect you tried these and encountered runtime errors. Those runtime errors were because you did not allocate any memory. The corrected code would look like:
prefixes[c1] = malloc(strlen(tmp1)+1);
strcpy(prefixes[c1], tmp1);
And similarly for suffixes.
In production quality code you'd include error checking. And you'd want to make sure that you call free() on any pointer returned by the calls malloc(), once you had finished with it.
I'd also question the use of C variable length arrays, VLAs. In your code, prefixes, suffixes, tmp1 and tmp2 are all VLAs. Using VLAs can readily lead to stack overflow if you have large array dimensions. My instincts say that heap allocation is what you need here.

Resources