Stack overflow with pointers in C - c

I'm new in C, and I'm trying some exercises that I found.
In one of the exercises I'm trying to use a pointer to a string (a char array), but it doesn't work. It compiles, but when is executed, it throws "stack overflow" (well, I think is an "stack overflow" because I have it in spanish).
These are the problematic lines:
//This is the variable declaration, before this, there is the "main function" declaration
char entrada[100];
char *ult=entrada;
char cantidadstr[10];
int i,j,k = 0;
int res;
scanf ("%s",entrada);
printf ("\n%s",entrada);
//Here crashes
printf ("Hola %s",ult);
while (*ult != "\0"){
//And here there's more code
Thank you in advance!!
EDIT
(I can't answer me :))
Then, I'll post a bit more of code.
When I execute, after inserting data, it throws "Violación de segmento", and google says that means Stack Overflow
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
char entrada[1001*11*101];
/*Asi tenemos el tamano maximo:
1001 por las 1000 posibles lineas, mas la primera
11 por el tamano maximo del numero (1 + 9 ceros), mas el espacio o salto de linea siguiente
101 por el numero de numeros por linea, mas el primero
*/
char *ult=entrada;
char cantidadstr[10];
int i,j,k = 0;
int res;
memset (entrada,'\0',1001*11*101);
scanf ("%s",entrada);
printf ("\n%s",entrada);
//poniendo ese print ahi arriba, ese me lo muestra, por tanto, el fallo esta en el puntero de debajo de esta linea
printf ("Hola %s",ult);
while (*ult != "\0"){
if(*ult == "\n"){
if(i != 0){
printf("\n");
}
i++;
j = 0;
}
else if(i != 0){
if(*ult == " "){
j++;
k=0;
res = atoi(cantidadstr);
printf("%d ",res*2);
//Este es el otro cambio que hablaba
cantidadstr[10] = '\0';
}
else if(j != 0){
cantidadstr[k] = *ult;
}
}
k++;
*ult++;
}
return 0;
}
This is the exact and full code, with comments in spanish for another forum. The size of "entrada" is big enough for any data send in the exercise. The "memset" is just added. The second comment shows where it crashes
Thank you for your quick answer!!

The code before the while loop is fine as it compiles and runs correctly(as far as i can think)
But the while loop has an error i'm not sure how it compiled in your case.
because you have written
while (*ult != "\0"){
which gives compiler error as
*ult is of type char
"\0" is of type const char*
you have to convert "\0" to '\0'

The following line:
cantidadstr[10] = '\0';
will write past the end of cantidadstr, which is definitely bad and most likely causing your stack overflow. If you want to null terminate cantidadstr, use cantidadstr[9]= '\0';. Arrays in C are zero based, not one based, so the first element of an array of size N starts at [0] and the last referenceable element is [N-1].

Related

isalpha() function in C don't read

I'm trying to write the substitution cipher but, a part of it, in particular the one where it sees me if the inserted alphabet is composed only of text characters "a ... z", doesn't work me. Could you tell me why the isalpha function (alfabeto_sostitutivo), although I insert the normal alphabet, gives me 0 as a result? Thanks in advance for the time spent.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main () {
int caratteri_diversi_1 = 0, caratteri_diversi_2 = 0, b = 0, tutti_alpha = 0, alpha_minuscoli = 0, alpha_maiuscoli = 0;
char alfabeto_sostituzione [27];
printf ("Inserisci l'alfabeto di criptazione (inglese):\n");
fgets (alfabeto_sostituzione, sizeof(alfabeto_sostituzione), stdin);
if (strlen(alfabeto_sostituzione)==26) //se la lunghezza dell'alfabeto sostitutivo è giusta
{
printf("I due alfabeti sono lunghi uguale\n");
for (int c=0; alfabeto_sostituzione[c] != '\0'; c++)
{
if (isalpha(alfabeto_sostituzione[c])==1)
alpha_minuscoli++;
else if (isalpha(alfabeto_sostituzione[c])==2)
alpha_maiuscoli++;
}
tutti_alpha = alpha_minuscoli + alpha_maiuscoli;
printf("alpha_minuscoli: %d\n",alpha_minuscoli);
printf("alpha_maiuscoli: %d\n",alpha_maiuscoli);
printf("tutti_alpha: %d\n",tutti_alpha);
if (tutti_alpha < 26 )
printf("L'alfabeto inserito NON contiene solo caratteri dell'alfabeto\n");
}
}
By filling in the program, the following text is returned:
Inserisci l'alfabeto di criptazione (inglese):
abcdefghijklmnopqrstuvwxyz
I due alfabeti sono lunghi uguale
alpha_minuscole: 0
alpha_maiuscole:0
tutti_alpha: 0
L'alfabeto inserito NON contiene solo caratteri dell'alfabeto
isalpha(argument) and other related functions declared in ctype.h
return a non-zero(true) if the argument satisfies the condition
described, and zero(false) if not.
Since you are checking for lower and upper case characters, the ctype library already has functions islower(argument) and isupper(argument) defined.
You could use them in tandem with the isaplha function, like so......
for (int c=0; alfabeto_sostituzione[c] != '\0'; c++)
{
if (isalpha(alfabeto_sostituzione[c]))
{
if(islower(alfabeto_sostituzione[c]))
alpha_minuscoli++;
else
alpha_maiuscoli++;
}
}

What am I doing wrong with this array in C?

I need to know how many times does "Maria" appears in this array, but when I run it, it says that it appears 51 times, and I think its only like 8
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int g;
int i;
const char * nombres[40] = {"Sandra Marisol","Juan Luis","Perez Luis","Carlitos","Maria","Mariana", "Carlota","Anthony",
"Fernando Jan","Alfonso Roche","Julieta Zacatenco","Maria de los Angeles","Laura Jessica",
"Andrea Maria","Jose Maria","Andres Molina","Aline Derrant","Paquito","Luisa","Ana Maria",
"Caleb","Luis Fernando","Mario Alberto","Paula Monica","Otoniel","Elias Primero","Maurico Enrique",
"Anastasia Maria","Maria Juana","Juana de Arco","Aria Montgomery""Hanna Maria","Magdalena","David Green",
"Florian Drake","Edward Jones","Joakin Broder","Paar","Alicia Torres","Juan Pablo"};
for(i = 0; i>40; i++)
{
printf("%s\n", nombres[40]);
if(nombres[i] == "Maria")
g++;
}
if(g>0){
printf("El nombre de Maria aparece %d veces.", g);
}
else {
printf("El nombre de Maria NO aparece");
}
system("pause");
return 0;
}
if(nombres[i] == "Maria")
You can't compare strings like this. You need to use strstr() to look for substrings in a string.
Also,
printf("%s\n", nombres[40]); probably should have i instead of 40. And your comparison in the middle of your for loop above this is backwards.
And... probably more else wrong, but that is enough for me.
There are lots of error..... Let's see how much I could solve..xd
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int g=0;
int i;
const char * nombres[40] = {"Sandra Marisol","Juan Luis","Perez Luis","Carlitos","Maria","Mariana", "Carlota","Anthony",
"Fernando Jan","Alfonso Roche","Julieta Zacatenco","Maria de los Angeles","Laura Jessica",
"Andrea Maria","Jose Maria","Andres Molina","Aline Derrant","Paquito","Luisa","Ana Maria",
"Caleb","Luis Fernando","Mario Alberto","Paula Monica","Otoniel","Elias Primero","Maurico Enrique",
"Anastasia Maria","Maria Juana","Juana de Arco","Aria Montgomery""Hanna Maria","Magdalena","David Green",
"Florian Drake","Edward Jones","Joakin Broder","Paar","Alicia Torres","Juan Pablo"};
for(i = 0; i<40; i++)
{
printf("%s\n", nombres[i]);
if(!strcmp(nombres[i],"Maria"))
g++;
}
if(g>0){
printf("El nombre de Maria aparece %d veces.", g);
}
else {
printf("El nombre de Maria NO aparece");
}
return 0;
}
Here the counter variable g was not initialized. It should be initialized to 0 otherwize it contains some garbage value.then in for loop the condition was wrong the loop was not being executed because u write I>40 here i is initialized by 0 so condition get false and loop don't run.then printf in the loop contains nombres[40] which gives a nullpointer because you last name is hombres[39].then in if condition you can't just compare string like other variable you have to use lib function which is strcmp which means string compare.
In following conditions
strcmp(s1,s2);
**
*if s1==s2 then it returns 0.
If s1>s2 then it returns 1
If s1<s2 it returns -1
So I wrote !strcmp();
So if string matches it will return 0 and '!' Converts it to 1.
Hope this works.kudos.

string pointers not working between functions

I am trying to assign different error messages to the error variable in each case by passing a pointer to the string between functions but for any reason is not working well.
Here is the code:
//This function takes a pointer to a char.
int lee(Fecha *f, char *error){
int checking;
printf("Introduzca una fecha compuesta por día, mes, y año\n");
checking = scanf("%i %i %i", &f->day, &f->month, &f->year);
printf("%d\n", checking);
switch (checking){
case 0:
//The message is assigned to the space where error points to.
*error = "Formato de fecha incorrecto. El día debe ser un entero.";
break;
case 1:
*error = "Formato de fecha incorrecto. El mes debe ser un entero.";
break;
case 2:
*error = "Formato de fecha incorrecto. El año debe ser un entero.";
break;
}
return (checking == 3);
}
int main(){
Fecha f;
//error is declared like a pointer
char * error;
int ret;
//The pointer is passed to the function as argument.
ret = lee(&f, error);
printf("%s", error);
return 0;
}
And the output:
user#console:~/$ ./Sesion1
Introduzca una fecha compuesta por día, mes, y año (o 0 0 0 para terminar el programa)
23 dfgadkfhgsñdgh 5
1
Segmentation fault
Since you want to make an output to the string, you need to pass pointer to your char*, so you need to pass error as char**.
So the function will be
int lee(Fecha *f, char **error){
int checking;
printf("Introduzca una fecha compuesta por día, mes, y año\n");
checking = scanf("%i %i %i", &f->day, &f->month, &f->year);
printf("%d\n", checking);
switch (checking){
case 0:
//The message is assigned to the space where error points to.
*error = "Formato de fecha incorrecto. El día debe ser un entero.";
break;
case 1:
*error = "Formato de fecha incorrecto. El mes debe ser un entero.";
break;
case 2:
*error = "Formato de fecha incorrecto. El año debe ser un entero.";
break;
}
return (checking == 3);
}
int main(){
Fecha f;
//error is declared like a pointer
char * error;
int ret;
//The pointer is passed to the function as argument.
ret = lee(&f, &error);
printf("%s", error);
return 0;
}
Also, you should consider not leaving pointers without value after declaration like you did with char* error in main().
The problem is, when you have a pointer that is not initialized and then you forget to give it a value or something like this, it can point anywhere within your application memory (or beyond it). Virtual memory protects you from reading and writing to others applications memory (generally speaking), but you can have a case where the pointer happens to point to some data inside your application. And if you then use this pointer to write or read, you will have unpredictable result, ranging from just displaying erroneous data to corrupting data or crashing application, which you obviously do not want.
You need to pass a pointer to your function output parameters. Since your output parameter is char*, the pointer to it is char**.
To fix, change the corresponding lines to:
int lee(Fecha *f, char **error);
// ...
ret = lee(&f, &error);

My C program prints 0xE instead of 0x0E in Keccak implementation

Im working on an implementation of Keccak(SHA-3) and for example I got this:
Keccak("abc") = 3A985DA74FE225B245C172D6BD390BD855F86E3E9D525B46BFE24511431532
Instead of (according: http://www.di-mgt.com.au/sha_testvectors.html)
3A985DA74FE225B2045C172D6BD390BD855F086E3E9D525B46BFE24511431532
As you can see my program miss a "0x00" and Im not sure what I am doing wrong.
Sorry guys here it is my main method code:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include "round.h"
#include "keccak.h"
#define TAM_MAX_ENTRADA 4096 /*Especificacion del numero de caracteres de la entrada*/
int main(int argc, char *argv[])
{
int32_t sha3Tipo; /*Nos dice el tipo de SHA3*/
char Mensaje[TAM_MAX_ENTRADA]; /*Array de caracteres donde guardamos el mensaje de entrada*/
printf("Elige el tamaño de salida (224,256,384,512): ");
scanf("%d",&sha3Tipo);
if(argc == 1)
{
strcat(Mensaje,""); /*Si no nos han pasado argumentos significa que es un string vacio*/
}
else
{
strcpy(Mensaje,argv[1]); /*Copiamos la primera palabra en el array de caracteres*/
}
for(int32_t i = 2; i<argc; i++)
{
strcat(Mensaje," "); /*Si tenemos mas de una palabra entonces anadimos */
strcat(Mensaje,argv[i]);
}
int32_t size = strlen(Mensaje);
int32_t *psize = &size;
uint8_t *newmessage;
newmessage=keccak((uint8_t *)Mensaje, *psize, sha3Tipo);
printf("Keccak(\"%s\") = ",Mensaje);
for(int32_t i =0; i<sha3Tipo/8; i++)
{
printf("%X", *(newmessage+i));
}
printf("\n");
return 0;
}
Perhaps you're losing the leading zeroes when converting the numbers into hexadecimal strings? For example, consider the following code:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("Without formatting: %x and %x\n", 12, 99);
printf("With formatting: %02x and %02x\n", 12, 99);
return 0;
}
When run, the output is:
Without formatting: c and 63
With formatting: 0c and 63
I'm thinking that your 4 and 8 should be 04 and 08, but they are not being formatted correctly.

Why the last iteration repeats?

My question refers to the while(!feof(arch)) that repeats the last registry two times. Thanks if you take some of your time to answer. I'm in first year learning basics.
The information is on an archive, so the first input shouldn't be 's' because it isn't the first time to input. Then the program list the infomation but the last registry repeats two times.
#include <stdio.h>
typedef struct{
int legajo;
char nombre[30];
int ingreso;
int pparcial;
int sparcial;
} reg_alumno;
reg_alumno funcionleer(void);
typedef FILE * archivo; //Se define el tipo de dato "archivo".
archivo arch; //Se declara una variable de archivo.
int main(void){
reg_alumno alumno,alu;
int ca,i,j=0;
char respuesta;
printf("Desea ingresar datos por primera vez?");
scanf("%c",&respuesta);
printf("Ingrese cantidad alumnos");
scanf("%d",&ca); //Pide cantidad alumnos
if(respuesta=='s'){
arch = fopen("alumnos.dat","w"); //Crear archivo para escribir, crea si no existe)
for(i=0;i<ca;i++){
alumno = funcionleer(); //Lee alumno
fseek(arch,sizeof(reg_alumno)*i,SEEK_SET); //Busca la última posición del archivo
fwrite(&alumno,sizeof(reg_alumno),1,arch); //Escribe en la última posición
}
}
else{
arch = fopen("alumnos.dat","r+");
while(!feof(arch)){
fseek(arch,sizeof(reg_alumno)*j,SEEK_SET); //Pasa de registro en registro(alumno en alumno).
fread(&alu,sizeof(reg_alumno),1,arch); //Trae a la memoria principal un alumno
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}
}
fclose(arch); //Cierra el archivo
}
reg_alumno funcionleer(void){ //Función leer
reg_alumno alumno;
printf("Ingrese el numero de legajo:\n");
scanf("%d",&alumno.legajo);
printf("Ingrese el nombre:\n");
scanf("%s",alumno.nombre);
return(alumno);
}
Good to check result of IO operations #WhozCraig.
The code's problem is that its prints even if fread() fails.
// No check of return value.
fread(&alu,sizeof(reg_alumno),1,arch);
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
Code uses feof() incorrectly. Many SO posts on that.
Since OP implies code is required to use feof() by teacher: following are 2 good ways to use feof()
for (;;) {
if (fseek(arch,sizeof(reg_alumno)*j,SEEK_SET)) break;
if (fread(&alu,sizeof(reg_alumno),1,arch) == 0) break;
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}
// If loop quit because of EOF
if (feof(arch)) printf("Success");
else if (!ferror(arch)) printf("IO Error");
Or
for (;;) {
if (fseek(arch,sizeof(reg_alumno)*j,SEEK_SET)) break;
fread(&alu,sizeof(reg_alumno),1,arch);
if (!feof(arch)) break;
if (!ferror(arch)) break;
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}

Resources