Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Σου απάντησε ο defacer πως γίνεται. Την C δεν τη νοιάζει πόσα στοιχεία έχει ο πίνακάς σου (ή ακόμη και αν είναι πίνακας ή τον μεταχειρίζεσαι εσύ σαν πίνακα). Ας πάρουμε το απλό σενάριο που έχουμε ένα πίνακα ακεραίων (πχ int k[10]) και ότι ο τύπος int έχει μέγεθος 4. Όταν εσύ δήλωσες τον πίνακα δεσμεύτηκε για αυτόν μια περιοχή μνήμης και από εκεί και πέρα είναι γνωστό ότι η μεταβλητή k αντιστοιχεί στην διεύθυνση Χ. Όταν εσύ πας να προσπελάσεις το 4ο στοιχείο και γράφεις k[3] = 5, η διαδικασία που γίνεται είναι να παίρνει την διεύθυνση X που αντιστοιχεί στο 1ο στοιχείο και να προσθέτει 3 φορές 4 bytes που καταλαμβάνει ο κάθε ακέραιος. Έτσι δηλαδή προσπελαύνεις την διεύθυνση X+12. Αν γράψεις x[30] = 5, θα πάει και θα γράψει στην διεύθυνση X+120 χωρίς να νοιάζεται που αυτή η διεύθυνση είναι εκτός του πίνακά σου. Αν αυτή η περιοχή μνήμης ανήκει στο πρόγραμμά σου και έχεις δικαιώματα εγγραφής, θα γράψει εκεί κανονικά σβήνοντας ότι υπάρχει εκεί που μπορεί να είναι σημαντικό. Αν δεν έχεις δικαιώματα εγγραφής, θα βαρέσει segmentation fault.

 

hmmm καταλαβα....δηλαδη εγώ συνεχίζω να διαχειρίζομαι τον πίνακα σαν να έχει τα στοιχεία που έχω δηλώσει :)

  • Απαντ. 1,6k
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοσ.

Aυτο που εστειλα ειναι το πρόβλημα μου...δεν είναι κατι άλλο σε αλλο κώδικα

Πως γινετε να μου τυπώνει στοιχειο του πίνακα που δεν υπάρχει????

 

Πώς γίνεται να σου τυπώνει γενικά όταν ο κώδικας δεν έχει καμία εντολή που μπορεί να τυπώσει οτιδήποτε;

Δημοσ.

 

 

hmmm καταλαβα....δηλαδη εγώ συνεχίζω να διαχειρίζομαι τον πίνακα σαν να έχει τα στοιχεία που έχω δηλώσει :)

 

Ναι. Εσύ θα πρέπει να φροντίσεις να διαχειρίζεσαι τόσα στοιχεία όσα έχεις δηλώσει αλλιώς θα γράψεις σε περιοχές που δεν πρέπει. Όπως αν βάλεις ένα κουτί χωρητικότητας 1 λίτρου κάτω από τη βρύση και την αφήσεις ανοιχτή για ώρες αυτή θα συνεχίσει να τρέχει άσχετα που γέμισε το κουτί, έτσι και η C θα γράψει και πέρα από τον πίνακά σου αν έτσι της πεις γιατί εμπιστεύεται τη κρίση σου.

Δημοσ.

Πώς γίνεται να σου τυπώνει γενικά όταν ο κώδικας δεν έχει καμία εντολή που μπορεί να τυπώσει οτιδήποτε;

 

εεε ενταξ , δεν το εγραψα στον κωδικα που ανεβασα

 

Ναι. Εσύ θα πρέπει να φροντίσεις να διαχειρίζεσαι τόσα στοιχεία όσα έχεις δηλώσει αλλιώς θα γράψεις σε περιοχές που δεν πρέπει. Όπως αν βάλεις ένα κουτί χωρητικότητας 1 λίτρου κάτω από τη βρύση και την αφήσεις ανοιχτή για ώρες αυτή θα συνεχίσει να τρέχει άσχετα που γέμισε το κουτί, έτσι και η C θα γράψει και πέρα από τον πίνακά σου αν έτσι της πεις γιατί εμπιστεύεται τη κρίση σου.

οκ καταλαβα

 

 

 

Ευχαριστω πολύ

Δημοσ.

Σου απάντησε ο defacer πως γίνεται. Την C δεν τη νοιάζει πόσα στοιχεία έχει ο πίνακάς σου (ή ακόμη και αν είναι πίνακας ή τον μεταχειρίζεσαι εσύ σαν πίνακα).

 

Ας πάρουμε το απλό σενάριο που έχουμε ένα πίνακα ακεραίων (πχ int k[10]) και ότι ο τύπος int έχει μέγεθος 4. Όταν εσύ δήλωσες τον πίνακα δεσμεύτηκε για αυτόν μια περιοχή μνήμης και από εκεί και πέρα είναι γνωστό ότι η μεταβλητή k αντιστοιχεί στην διεύθυνση Χ. Όταν εσύ πας να προσπελάσεις το 4ο στοιχείο και γράφεις k[3] = 5, η διαδικασία που γίνεται είναι να παίρνει την διεύθυνση X που αντιστοιχεί στο 1ο στοιχείο και να προσθέτει 3 φορές 4 bytes που καταλαμβάνει ο κάθε ακέραιος. Έτσι δηλαδή προσπελαύνεις την διεύθυνση X+12. Αν γράψεις k[30] = 5, θα πάει και θα γράψει στην διεύθυνση X+120 χωρίς να νοιάζεται που αυτή η διεύθυνση είναι εκτός του πίνακά σου. Αν αυτή η περιοχή μνήμης ανήκει στο πρόγραμμά σου και έχεις δικαιώματα εγγραφής, θα γράψει εκεί κανονικά σβήνοντας ότι υπάρχει εκεί που μπορεί να είναι σημαντικό. Αν δεν έχεις δικαιώματα εγγραφής, θα βαρέσει segmentation fault.

 

albNik αυτο που λεει ο ημιθεος μπορει να ειναι και το παρακατω

 

>
#include<stdio.h>

int main(void)
{
	
    int i , a[3] = {0};
	
    for(i = 0; i < 4 ; a[i++] = 2 )
		    printf(" %d ", i );   
	 
return 0;
}

 

Ακριβως και αυτο το παραδειγμα δειχνει πως μπορει μια υπερχειλιση στον πινακα να γράψει πανω σε σημαντικά δεδομένα.

Το i οπως και να το κανεις σαν μετρητης ειναι σημαντικο για ενα loop. Πχ εδω παράγει ατέρμονα βροχο δημιουργοντας γενικοτερο προβλημα

Δημοσ.

 

 

To δοκιμασα ρε συ. Αλλα μου το βγαζει κανονικα...

 

 

 

>

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

int main( void )
{

    char str1[]="hello";
    char str2[]="hellom";

    strcpy(str1,str2);

    puts(str1);

    return 0;
}

 

OUTPUT:

 

>

hellom

 

 

Κατα τύχη δουλευει. Για αυτο και δεν μπορεσα να εχω ξεκαθαρη εικονα.

 

@ημιθεε οκ.

 

Δοκίμασε με: char str2[] = "sdjdslk jfs dfjdslkfj sdklfj dslkfj sdfj dsaf dsj hdsg sk hjhsg fdgsdf";

Δημοσ.

@migf1 και παλι τα ιδια... κανονικα μου το βγαζει και παλι

 

>

Copied from insomnia
sdjdslk jfs dfjdslkfj sdklfj dslkfj sdfj dsaf dsj hdsg sk hjhsg fdgsdf
sdjdslk jfs dfjdslkfj sdklfj dslkfj sdfj dsaf dsj hdsg sk hjhsg fdgsdf

 

>

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

int main( void )
{

	 char str1[]="hello";
	 char str2[]="sdjdslk jfs dfjdslkfj sdklfj dslkfj sdfj dsaf dsj hdsg sk hjhsg fdgsdf";

	 strcpy(str1,str2);

	 puts("Copied from insomnia");
	 printf("sdjdslk jfs dfjdslkfj sdklfj dslkfj sdfj dsaf dsj hdsg sk hjhsg fdgsdf\n");
	 printf("%s" , str1);

	 return 0;
}

 

Δεν θα ζαλιζα το θρεντ αμα δεν υπηρχε λογος. Και το εβλεπα και απο μονος μου με 3-4 γραμμες κωδικα οπως ειπες και εσυ δεν ειναι καθολου δυσκολο. Tελοςπαντων προφανως και υπάρχει δικαιωμα εγγραφης για αυτο και "δουλευει" .

Δημοσ.

@migf1 και παλι τα ιδια... κανονικα μου το βγαζει και παλι

>
Copied from insomnia
sdjdslk jfs dfjdslkfj sdklfj dslkfj sdfj dsaf dsj hdsg sk hjhsg fdgsdf
sdjdslk jfs dfjdslkfj sdklfj dslkfj sdfj dsaf dsj hdsg sk hjhsg fdgsdf

 

http://www.insomnia.gr/topic/437533-%CE%B5%CF%81%CF%89%CF%84%CE%AE%CF%83%CE%B5%CE%B9%CF%82-%CE%B3%CE%B9%CE%B1-c/page__st__1170#entry5119576

 

Τι τιμή έχει το i ?

Δημοσ.

http://www.insomnia....70#entry5119576

 

Τι τιμή έχει το i ?

 

>

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

int main( void )
{

	 char str1[]="hello";
	 char str2[]="sdjdslk jfs dfjdslkfj sdklfj dslkfj sdfj dsaf dsj hdsg sk hjhsg fdgsdf";
	 int x=3 , y=4 , z=5;

	 strcpy(str1,str2);

	 puts("Copied from insomnia");
	 printf("sdjdslk jfs dfjdslkfj sdklfj dslkfj sdfj dsaf dsj hdsg sk hjhsg fdgsdf\n");
	 printf("%s" , str1);

	 printf("%d , %d , %d " , x , y , z);

	 return 0;
}


 

Τα x,y,z να δεις τι τιμες έχουν :P

Τεσπα κανεις δεν αμφισβητει το overwrite .... το μονο που μου εκανε εξαρχης εντυπωση ειναι

πως διαολο καταφερνει και "δουλευει" η puts /printf.... στο δικο μ συστημα τουλαχιστον.

Δημοσ.

 

Δεν θα ζαλιζα το θρεντ αμα δεν υπηρχε λογος. Και το εβλεπα και απο μονος μου με 3-4 γραμμες κωδικα οπως ειπες και εσυ δεν ειναι καθολου δυσκολο. Tελοςπαντων προφανως και υπάρχει δικαιωμα εγγραφης για αυτο και "δουλευει" .

 

Δοκίμασε να ορίσεις τα x,y,z μεταξύ ορισμού str1 & str2.

Δημοσ.

>

int read_line( char str[] , int n )
{
int ch , i =0;

while( (ch = getchar()!='\n')
if( i < n )
str[i++] = ch;
str[i]='\0';

return i;    // Επέστρεψε τον αριθμο των χαρακτήρων που έχεις αποθηκεύσει στο str
}

 

Για την παρπάνω συνάρτηση δεν θα ήταν καλύτερο να βάζαμε το i<n μέσα στο while αντι να χρησιμοποιούμε μια εξτρα συνθηκη που φαινεται περιττή?

 

> while( (ch= getchar() != '\n' && i<n ) 

Δημοσ.

Τι εννοείς ως "περιττή σύγκριση";

 

Και στις 2 περιπτώσεις 2 συγκρίσεις γίνονται, αλλά στη 2η περίπτωση γλιτώνεις περιττά iterations του loop...

 

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

#define MAXINPUT    (2+1)

/* ----------------------------------- */
int read_line( char str[] , int n )
{
   int ch, i=0;

   while ( '\n' != (ch = getchar()) ) {
       if ( i < n )
           str[i++] = ch;
       putchar('*');
   }
   str[i] = '\0';

   putchar('\n');
   return i;    // Επέστρεψε τον αριθμο των χαρακτήρων που έχεις αποθηκεύσει στο str
}

/* ----------------------------------- */
int readline( char str[] , int n )
{
   int ch, i =0;

   while( '\n' != (ch = getchar()) && i < n ) {
       str[i++] = ch;
       putchar('*');
   }
   str[i] = '\0';

   putchar('\n');
   return i;    // Επέστρεψε τον αριθμο των χαρακτήρων που έχεις αποθηκεύσει στο str
}

/* ----------------------------------- */
int main( void )
{
   char input[MAXINPUT] = {'\0'};

   printf( "%d\n", read_line(input, MAXINPUT) );
   printf( "(%zu): %s\n", strlen(input), input );

   printf( "%d\n", readline(input, MAXINPUT) );
   printf( "(%zu): %s\n", strlen(input), input );

   system("pause");  // Windows only
   return 0;
}                                       

// INPUT/OUTPUT:

1234567890
**********
3
(3): 123
1234567890
***
3
(3): 123

 

Επίσης έτσι όπως τα έχεις τα loops, βγαίνεις εκτός ορίων του input όταν σου δίνουν στην είσοδο πλήθος χαρακτήρων >= n. Στο παράδειγμα θα έπρεπε να κρατάει το "12" και όχι το "123".

Δημοσ.

migf1 ναι το βλεπω αυτο που λες..... τον κώδικα τον έχω πάρει απο τον King και του έχω βαλει κάποιες μικρες βελτιώσεις μεσα πχ να μην δεχεται αρνητικες ημερομηνιες .

 

>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_REMIND 50
#define MSG_LEN 3
int read_line(char str[] , int n);

int main( void )
{
char reminders[MAX_REMIND][MSG_LEN+3];
char day_str[3] , msg_str[MSG_LEN+1];
int day , i , j , num_remind=0;

for(;{
if( num_remind == MAX_REMIND)
{
printf("-- No space left --\n");
break;
}
 printf(" Enter day and reminder : ");
 scanf("%2d", &day);

 if( day == 0 || day < 0)
 break;

 sprintf(day_str , "%2d" , day);
 read_line(msg_str, MSG_LEN);

 for(i=0; i < num_remind; i++)
 if(strcmp(day_str , reminders[i]) < 0 )
 break;

 for(j=num_remind; j>i; j--)
 strcpy(reminders[j], reminders[j-1]);

 strcpy(reminders[i] , day_str);
 strcat(reminders[i] , msg_str);

 num_remind++;
}

if( !num_remind )
exit(1);

printf("\nDay Reminder\n");

for(i=0; i < num_remind; i++)
printf(" %s\n" , reminders[i]);

 return 0;
}
int read_line(char str[] , int n)
{
int ch , i =0 ;

while( (ch= getchar()) !='\n' && i<n)
//if( i < n )
str[i++]= ch;

str[i]='\0';

return i;
}

 

Καμια διόρθωση σε αυτο που επισημαινεις υπάρχει ?

Δημοσ.

migf1 ναι το βλεπω αυτο που λες..... τον κώδικα τον έχω πάρει απο τον King και του έχω βαλει κάποιες μικρες βελτιώσεις μεσα πχ να μην δεχεται αρνητικες ημερομηνιες .

 

 

 

>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_REMIND 50
#define MSG_LEN 3
int read_line(char str[] , int n);

int main( void )
{
char reminders[MAX_REMIND][MSG_LEN+3];
char day_str[3] , msg_str[MSG_LEN+1];
int day , i , j , num_remind=0;

for(;{
if( num_remind == MAX_REMIND)
{
printf("-- No space left --\n");
break;
}
    printf(" Enter day and reminder : ");
    scanf("%2d", &day);

    if( day == 0 || day < 0)
    break;

    sprintf(day_str , "%2d" , day);
    read_line(msg_str, MSG_LEN);

    for(i=0; i < num_remind; i++)
    if(strcmp(day_str , reminders[i]) < 0 )
    break;

    for(j=num_remind; j>i; j--)
    strcpy(reminders[j], reminders[j-1]);

    strcpy(reminders[i] , day_str);
    strcat(reminders[i] , msg_str);

    num_remind++;
}

if( !num_remind )
exit(1);

printf("\nDay Reminder\n");

for(i=0; i < num_remind; i++)
printf(" %s\n" , reminders[i]);

    return 0;
}
int read_line(char str[] , int n)
{
int ch , i =0 ;

while( (ch= getchar()) !='\n' && i<n)
//if( i < n )
str[i++]= ch;

str[i]='\0';

return i;
}

 

 

Καμια διόρθωση σε αυτο που επισημαινεις υπάρχει ?

 

Δεν μπορώ να δω τώρα τον κώδικα, αλλά αν ρωτάς πως να το κάνεις να κρατάει το σωστό "12" αντί για το λάθος "123", τότε θελει i < n-1 αντί για i < n.

Δημοσ.

Οκ. Ειναι απο το βιβλιο του King Σελ. 295 κανα καλο γρηγορο παραδειγμα και

επεξηγηση για την sprintf έχεις ???? έχω ζαλιστει .....

 

p.s Παντως οταν ευκαιρησεις δες λιγο τον κωδικα.....

Επισκέπτης
Αυτό το θέμα είναι πλέον κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...