PDA

Visualizza la versione completa : [C] Programma termina con errore su chiamata a strcat()


SuperGulp1970
01-07-2009, 17:51
Ciao
qualcuno mi sa aiutare ?



#include <string>
#include <stdio.h>

int main (int argc, char *argv[])
{
int i;
char *c;
char *d;
char *e;
char *l;
char *p;
char *a;
l=argv[1];
p=argv[2];
printf ("Argc=%d\n",argc);
for (i=1; i<argc; i++)
{
c=argv[i];
printf ("argv[%d]=%s\n",i,c);
strcat (d,l);
if ((i+1)<argc)
strcat (d,":");
}
printf ("d=%s\n",d);
printf ("-----------> FINO A QUI TUTTO OK <--------------\n");
printf ("l=%s\n",l);
printf ("-----------> FINO A QUI TUTTO OK <--------------\n");
strcat(a,l);
}


infase di esecuzione si chiude con un errore all'ultima riga che concettualmente mi sembra essere uguare a:
strcat (d,l);

????????????????

Sbaglio ??????????????


grazie 10000!

LeleFT
01-07-2009, 17:59
Il regolamento impone una certa rigidità riguardo ai titoli, più che altro per mantenere l'ordine e permettere anche agli altri di capire di cosa si parla in una discussione... in futuro, quindi, cerca di scrivere dei titoli che descrivano il contenuto della discussione.


Modifico io.

PS: se il programma si chiude con un errore... riporta l'errore.


Ciao. :ciauz:

SuperGulp1970
01-07-2009, 18:27
ok ... grazie...

In fase di esecuzione ... si chiude con il classico errore di windows .. GENERICO !!! x capirci ti chiede se vuoi spedire il report o no !!

MItaly
01-07-2009, 20:57
Sia la prima strcat che la seconda sono errate, visto che sia d che a sono puntatori non inizializzati. In pratica, stai dicendo al programma di andare a scrivere in un'area di memoria indefinita. Per poter utilizzare quei puntatori devi prima assegnarci l'indirizzo di della memoria allocata (ad esempio con malloc).

MacApp
01-07-2009, 20:58
Compilando al volo il tuo codice con


$ gcc --version
i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367)
Copyright (C) 2005 Free Software Foundation, Inc.


si ottiene:


$ gcc main.c
main.c:1:18: error: string: No such file or directory
main.c: In function 'main':
main.c:20: warning: incompatible implicit declaration of built-in function 'strcat'
main.c:28: warning: incompatible implicit declaration of built-in function 'strcat'


correggendo quindi <string> in <string.h>

si ottiene:


$ gcc -Wall -ansi -pedantic -Wextra -Wconversion main.c
main.c: In function 'main':
main.c:9: warning: unused variable 'e'
main.c:29: warning: control reaches end of non-void function

cancellando quindi la non usata variabile "e" e aggiungendo l'istruzione "return 0;" a fine main finalmente riusciamo a compilare senza problemi.

Dando ora un'occhiata veloce al codice, si vede che la prima istruzione:


l=argv[1];

produrrà un comportamento indefinito se il programma verrà invocato con zero argomenti (oltre al nome del programma stesso).

Dalla seconda istruzione si vede che:


p=argv[2];

produrrà un comportamento indefinito se il programma verrà invocato con meno di due argomenti (oltre al nome del programma stesso).

dalla strcat nel corpo del ciclo for:


strcat (d,l);

e considerata la documentazione della strcat stessa:


$ man strcat
#include <string.h>

char *
strcat(char * restrict s, const char * restrict append);
...
DESCRIPTION
The strcat() and strncat() functions append a copy of the null-terminated
string append to the end of the null-terminated string s, then add a ter-
minating `\0'. The string s must have sufficient space to hold the
result.

si intuisce che è normale che il tuo programma abbia un comportamento indefinito.
Perciò ti va bene che vada solo in crash senza causare altri danni.
;-)

oregon
01-07-2009, 21:34
Originariamente inviato da SuperGulp1970
In fase di esecuzione ... si chiude con il classico errore di windows .. GENERICO !!! x capirci ti chiede se vuoi spedire il report o no !!

Solo per essere precisi ... il messaggio di Windows che hai NON e' affatto generico, ma riporta, sapendole leggere tutte le indicazioni necessarie a capire il problema (che, FRA L'ALTRO, puo' essere riportato anche a Microsoft).

In ogni caso, un "access violation" (e questo mi sembra il caso) e' quasi SEMPRE riferito all'utilizzo non corretto di un puntatore ... e quindi sai subito cosa cercare.

Poi, se esegui il programma passo-passo, ti accorgi subito quale riga genera l'errore e la puoi studiare con particolare attenzione all'uso dei puntatori.

SuperGulp1970
02-07-2009, 09:48
ok .. grazia a tutti per l'aiuto....


1) chiedo scusa per il discorso dell'orrore ma ho postato il messaggio dopo una nottata in bianco !!!

2) per quanto riguarda il warring della variabile non utilizzata... è un avanzo di qualche prova !!! :confused:

3) premesso che ogni volta che chiamo il programma invoco almeno due parametri :mame:

4) in fase di compilazione dev c++ non mi da nessun warring (nemmeno per la variabile non utilizzata)

Vediamo se ho capito (viso la premessa del punto 3)

dovrei aggiungere :
a=(char*)malloc(120*sizeof(char));
d=(char*)malloc(120*sizeof(char));

dove sizeof(char) può essere sostituinto con 1.

così alloco lo spazio di memoria e che se il comando
strcat (d,c);
funziona senza il malloc è solo questione di :ciapet: (fortuna).


Il mio scopo finale dovrebbe essere questo:


#include <string>
#include <stdio.h>

int main (int argc, char *argv[])
{
int i;
char *c;
char *d;
char *l;
char *p;
char *a;
a=(char*)malloc(120*sizeof(char));
d=(char*)malloc(120*sizeof(char));
a[119*sizeof(char)]='\0';
d[119*sizeof(char)]='\0';
a="blablabla ";
l=argv[1];
p=argv[2];
printf ("Argc=%d\n",argc);
for (i=1; i<argc; i++)
{
c=argv[i];
printf ("argv[%d]=%s\n",i,c);
strcat (d,c);
if ((i+1)<argc)
strcat (d,":");
}
printf ("d=%s\n",d);
printf ("-----------> FINO A QUI TUTTO OK <--------------\n");
printf ("l=%s\n",l);
printf ("-----------> FINO A QUI TUTTO OK <--------------\n");
strcat(a,l);
printf ("a=%s\n",a);
printf ("****************");
}



ma l'output finale è:
Argc=3
argv[1]=admin
argv[2]=ciao
d=Ï♦>admin:ciao
-----------> FINO A QUI TUTTO OK <--------------
l=admin
-----------> FINO A QUI TUTTO OK <--------------


Notare che si aggiunge a d dei caratteri e poi si chiude con lo stesso errere di prima.

Un'altra domanda: ma se inizializzo il puntatore a="bla bla bla bla "; non sarebbe sufficiente per assegnarli lo spazio in memoria ?


Grazie ancora a tutti

SuperGulp1970
02-07-2009, 09:49
ops mi sono dimenticare di taggare l'output e le parti di codice !!!

MItaly
02-07-2009, 10:01
Originariamente inviato da SuperGulp1970
dove sizeof(char) può essere sostituinto con 1.

Dove sizeof(char) lo puoi tranquillamente omettere, visto che per definizione è uguale a 1.


così alloco lo spazio di memoria e che se il comando
strcat (d,c);
funziona senza il malloc è solo questione di :ciapet: (fortuna).

Esatto.
Un paio di questioni "formali":


a=(char*)malloc(120);
d=(char*)malloc(120);
a[119]='\0'; /* qui sizeof(char) non è solo inutile, è sbagliato, gli indici si riferiscono agli elementi, non ai byte */
d[119]='\0';

Errore grave:


a="blablabla ";

Così facendo stai assegnando ad a un nuovo puntatore a memoria di sola lettura situata nella tabella delle stringhe dell'eseguibile. Semmai:


strcpy(a,"blablabla ");



Un'altra domanda: ma se inizializzo il puntatore a="bla bla bla bla "; non sarebbe sufficiente per assegnarli lo spazio in memoria ?

Gli assegni della memoria di sola lettura e delle dimensioni esatte della stringa "bla bla bla bla ", che non puoi modificare in nessun modo (difatti il tipo delle stringhe inserite nel codice del programma è const char *).

Loading