char*** causes segfault after one run of for loop - c

I am trying to access and manipulate a list of strings from a function in C but for some reason i get a seg fault as soon as the loop in the function does 1 pass.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void print_stuff(char*** what)
{
for(int i = 0; i < sizeof(*what); ++i)
{
*what[i] = malloc(5 * sizeof(*what));
*what[i] = "hello";
printf("%s\n", *what[i]);
}
}
int main(void)
{
char** hello;
hello = malloc(20 * sizeof(*hello));
print_stuff(&hello);
}

I was going to write a long, detailed answer, but it got too long considering the amount of problems I can think of about this code. So here is the short version. It looks like what you are trying to do can be done just like this.
#include <stdio.h>
int main(void)
{
for(int i = 0; i < 20; i++) {
printf("hello\n");
}
}
I fail to understand the purpose of the rest of the code. It uselessly allocates memory, does not even do that correctly. And it's just wrong. Maybe more context is needed for what you are trying to achieve.

Related

Get output line by line from another function (another source file)?

I have two source files: counter.c and main.c:
counter.c:
#include <stdio.h>
int counter(void) {
for(int i = 0; i < 5; i++)
printf("%d\n", i);
return 0;
}
main.c:
#include <stdio.h>
int counter(void);
int main(void) {
char *line;
counter();
return 0;
}
What I want to do is to have each line that counter() prints to be assigned to the line variable so I can do printf("%s\n", line) myself in main.c.
(edit) Unfortunately, this example doesn't translate well to my actual code so maybe I'll just put it here:
https://github.com/venetwork/venet/blob/master/venet-show.c
What I need is to access the result of running this code on a line by line basis in a different source file (GTK3 GUI). The main function for my combined code will be in this file so main() in venet-show.c should be changed to, say, show(). As of this moment I just use an IO Channel (https://developer.gnome.org/glib/stable/glib-IO-Channels.html) to "stream" the output of venet-show.c to the GUI but I want to get ride of it. Any ideas?
So we pass an allocated memory address and not a pointer like you had to the function. This has storage for the result. Use the return snprintf to advance the pointer so not to overwrite previous results.
#include <stdio.h>
int counter(char *answer, size_t array_len) {
for(int i = 0; i < 5; i++)
{
size_t chars_printed = snprintf(answer, array_len, "%d\n", i);
answer+=chars_printed;
array_len-=chars_printed;
}
return 0;
}
int main(void) {
char line[10000];
counter(line, sizeof(line));
printf("%s", line);
return 0;
}

Why the code below excutes unexpected letters in the end of the string?

This is my code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int countNumber(char string[],int number_[]);
int countNumber(char string[]);
int main(){
char string[] = "tran_huynh_minh_phuc";
int num = countNumber(string)+1;
int *number = (int *) calloc(num, sizeof(int));
countNumber(string,number);
for(int i=0;i<num;i++){
printf("%d\n",number[i]);
}
fflush(stdin);
char a[3][14];
strncpy(a[2], string+5, 5);
printf("%s",a[2]);
}
int countNumber(char string[],int *number)
{ int count=0;
int num_i=1;
number[0]=-1;
for(int i=0; i<strlen(string); i++)
{
if(string[i]=='_')
{ number[num_i] = i;
num_i++;
}
}
return count;
}
int countNumber(char string[])
{ int count=0;
for(int i=0; i<strlen(string); i++)
{
if(string[i]=='_')
{
count++;
}
}
return count;
}
this is my problem console results:
I am doing the program to get the substring which will get "tran","huynh","minh" from "tran_huynh_minh", however it is appearing some unexpected letters at the end of my substring. In addition, I tried many ways to fix it but it did not work. Can you find my mistakes?
Thanks
Minh Phuc
I think the intent for the bottom of the main block is something like this (this adds the null after the 'huynh' which was copied. By adding the null, when it goes to print a2, it knows when to stop. It looks like the desire was to put the second word in the array at index 2 (presumably being done in a loop once it was working or the like):
strncpy(a[2], string + 5, 5);
a[2][5] = '\0';
printf("%s", a[2]);
If you run something equivalent to this, you should see the expected output. However, you likely also see a warning on the strncpy function and considering using strncpy_s (depending what you are using to compile. It looks like you are on windows). If you replace the function call with strncpy_s (assuming Visual Studio), you will get the desired result without adding the null at the end separately. Note it expects a size of the destination array as a safeguard (14 in this case).
See this link as well as this one.

Array with int and char in C

I need to put 3 strings on an array[3][3].
I tried to do it with pointers, but I only receive a single character.
#include <stdio.h>
int array[3][3]
char thing[5] = "thing";
main()
{
thing = array[0][0];
printf("%s", array[0][0];
}
Try this. With due respect your code absolutely incorrect and need many changes. You need to update your programming skills too.
#include <stdio.h>
#include <string.h>
char array[3][6]={0};
char *thing = "this";
main()
{
strcpy(array[0],thing);
printf("%s\n", array[0]);
}

Whats wrong with this basic shell program? it will run fine for the first few commands but results always ends in a seg fault

I have to build a simple shell program using lex and c code. The lex portion is for breaking down the input. It has been provided for me and I'm not expected to change it. I'm in the process of getting my code to run basic commands like "ls". It seems to work the first few times I run the command but eventually always seg faults. Here is the lex code provided:
%{
int _numargs = 10;
char *_args[10];
int _argcount = 0;
%}
WORD [a-zA-Z0-9\/\.-]+
SPECIAL [()><|&;*]
%%
_argcount=0;
_args[0]=NULL;
{WORD}|{SPECIAL} {
if(_argcount < _numargs-1) {
_args[_argcount++]= (char *)strdup(yytext);
_args[_argcount]= NULL;
}
}
\n return (int)_args;
[ \t]+
.
%%
char **getln() {
return (char **)yylex();
}
This is the C code:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
extern char **getln();
int main() {
int i;
char **args;
int child1;
int status1;
int counter=0;
int argCount = 1;
char **array = (char **)malloc(1500 * sizeof(char *));
for (i = 0; i < 1500; ++i) {
array[i] = (char *)malloc(500);
}
strcpy(array[0],"ls\0");
array[1] = NULL;
while(1) {
args = getln();
printf("is error here?");
strcpy(array[0], args[counter]);
for(i = (counter+1); args[i] != NULL; i++) {
printf("\nRight before copying to subarray");
strcpy(array[argCount], args[i]);
argCount++;
}
array[argCount] = NULL;
if (strcmp(args[counter],"exit")==0) exit(0);
child1 = fork();
if(child1==0){
execvp(array[0], array);
printf("Unknown command, please try again.");
exit(1);
}
else{
while (wait(&status1) != child1);
}
for(i = 0; args[i] != NULL; i++) {
printf("Argument %d: %s\n argCount: %d", i, args[i], argCount);
}
argCount = 1;
counter++;
}
}
Thanks in advance for any advice. If there is some simple way to adjust the getln() function to overwrite the args array each time it is called that might be easier than what I am attempting but I have no idea how to go about that.
It seems like you have put
_argcount=0;
_args[0]=NULL;
at the top of the rules section in hopes that these statements would be executed at the beginning of yylex(). And you've noticed that they aren't executed (it keeps appending to the previous values because _argcount never goes back to 0).
The obvious thing to do is move those statements into getln() just before the yylex().
What you have now is a lexer that will ignore the string _argcount=0; in the input because it will match that pattern and there's no action to go with it. The second line is even cooler since the [0] is a character class. It makes the lexer ignore the string _args0=NULL;

passing of strings in C function

i have the following problems in C programming.
I have an array of strings stored as words[10][50]. I want to extract each of the string from the array and then pass it on to another function. I tried on the following:
#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
int Check_Anagram(char*,char*);
void main()
{
char words[10][20];
int i;
int flag;
for(i=0;i<3;i++)
{
scanf("%s\n",words[i][20]);
}
for(i=1;i<10;i++)
{
flag = Check_Anagram(words[i][20],words[i-1][20]);
}
getch();
}
int Check_Anagram(char *a,char *b)
{
printf("%s %s\n",a,b);
return 1;
}
This creates an exception during compiling.
Now i think that when i use the "printf" statement then this nomenclature works fine i.i words[i] prints the string "i" from the double dimension words array. When i try to do the same thing with the check function then the error occurs.
Can soemone point me how to do this passing ?
P.S. Please ignore any error in efficiency of program and likewise. I need your help and this is just a test program at learning string passing to a function
Thanks
You're passing words[i][20]. You need to pass words[i] instead in both loops. Try this:
for(i = 1; i < 3; i++) /* i < 3 */
{
flag = Check_Anagram(words[i], words[i-1]);
}
Another problem is that you're reading 3 strings and trying to print 10. So when you pass words[3] it contains garbage: printf tries to print garbage which need not be 0-terminated.
In the first for loop, when i is 0, you're pointing to words[-1], that's your exception.
flag = Check_Anagram(words[i][20],words[i-1][20]);
You are passing the 21st letter of each word the Check_Anagram. Instead you should pass the words themselves:
flag = Check_Anagram(words[i],words[i-1]);
You have a similar problem where you use scanf. To read a line from the console to each word you would use:
for(i=0;i<10;i++)
{
scanf("%s\n",words[i]);
}
#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
int Check_Anagram(char [],char []);
void main()
{
char words[10][20];
int i;
int flag;
for(i=0;i<3;i++)
{
scanf("%s\n",words[i]);
}
for(i=1;i<10;i++)
{
flag = Check_Anagram(words[i],words[i-1]);
}
getch();
}
int Check_Anagram(char a[],char b[])
{
printf("%s %s\n",a,b);
return 1;
}
I finally got it corrected thanks to the help of all users.
I have posted the corrected code for people who are struggling with passing of string extracted from an array of strings to another function. hope it helps.

Resources