簡體   English   中英

C - Malloc問題(可能還有別的)

[英]C - Malloc issue (maybe something else)

更新版本:

所以,我試圖在不使用scanf / fgets的情況下使用此代碼。 從用戶獲取字符,使用嵌套在for循環中的while循環將其放入指針數組中。

#define WORDLENGTH 15
#define MAXLINE 1000

int main()
{
    char *line[MAXLINE];
    int i = 0;
    int j;
    int n;
    char c;


    for (n=0; c!=EOF; n){
        char *tmp = (char *) malloc(256);
        while ((c=getchar())!=' '){
            tmp[i]=c;     // This is no longer updating for some reason. 
            i++;
            }
        line[n++]=tmp; // 
        i=0;
        printf("\n%s\n",line[n]); //Seg fault here
    }

    for(j = 0; j (lessthan) n; j++){
        printf("\n%s\n", line[j]);
        free (line[j]);
    }

    return 0;

所以,現在我遇到了一個段錯誤。 不確定為什么tmp [i]沒有正確更新。 仍在努力。

到目前為止,我從未在整個學期中學到很多關於編程的知識。 請繼續幫助我學習。 我喜歡這個。

您打印line[i] ,就在此之前,您將i設置為0.而是打印line[n]

此外,您忘記了終止0字符。 如果你將tmp為char數組然后在分配給line[n]之前進行strdup ,你的代碼將變得更容易。

sizeof(WORLDLENGTH) ,其中之一,是錯誤的。 malloc取整數,WORLDLENGTH是整數。 sizeof(WORLDLENGTH)將為您提供一個整數的大小,如果您為32位系統編譯,則為4,因此您將分配4個字節。

Btw - while ((c=getchar())!=' '||c!=EOF) - 你的意圖是什么? 如果b!= c,像(a!=b || a!=c)這樣的條件總是返回true,因為a和b都不可能。

並且,正如其他人指出的那樣,你打印出行line[i] ,其中我總是為0.你可能意味着line[n] 而且你不會終止tmp字符串。

而且沒有溢出檢查,所以如果一個單詞比WORDLENGTH長,你就會遇到邪惡的錯誤。

更改printf行 - 您需要打印line[n]而不是line[i]

首先你的malloc公式是錯誤的

 malloc(sizeof(char)*WORDLENGTH);

你需要為你的單詞長度分配一個char的大小(也就是15似乎有點小,你不計算詞典中最長的單詞或“iforgettoputspacesinmyphrasestoscrewtheprogrammer”案例lol不要害羞char很小你可以輕松打到256或512 ^^

 printf("\n%s\n",line[i]);

需要改為

int j = 0;

for(j=0;j<i;j++){
     printf("\n%s\n",line[j]);
}

你永遠不會改變,所以你總是打印相同的線

其他人已經告訴你代碼的一些具體問題,但他們似乎錯過的一件事是c應該是int ,而不是char 否則,與EOF的比較將無法按預期工作。

另外,你得到的段錯是由於這個順序:

line[n++]=tmp;
printf("\n%s\n",line[n]);

已經將 n遞增到下一個數組元素,然后嘗試打印它。 第二行應該是:

printf("\n%s\n",line[n-1]);

如果你只是想要一些有效的代碼(免費“做你想做的”許可),這里是我的代碼庫中一個有用的代碼片段。

我不確定為什么你認為fgets是要避免的,它實際上非常方便且非常安全。 我假設你的意思gets這不太方便,完全不安全。 你的代碼也容易出現緩沖區溢出,因為如果它得到很多既不是空格也不是文件末尾的字符,它會很樂意寫出超出分配區域的末尾。

通過一切手段,編寫自己的代碼,如果你教育自己,但該部分應檢查生產測試防彈代碼,看看它如何做。 而且,如果你不是在教育自己,那么你就不會因為不使用免費的代碼對自己造成傷害。

該片段如下:

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

#define OK       0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff)-1] = '\0';
    return OK;
}

// Test program for getLine().

int main (void) {
    int rc;
    char buff[10];

    rc = getLine ("Enter string> ", buff, sizeof(buff));
    if (rc == NO_INPUT) {
        printf ("No input\n");
        return 1;
    }

    if (rc == TOO_LONG) {
        printf ("Input too long\n");
        return 1;
    }

    printf ("OK [%s]\n", buff);

    return 0;
}

它是一個有用的行輸入函數,具有與fgets相同的緩沖區溢出保護,還可以檢測用戶輸入的行太長。 它還會拋棄太長線的其余部分,這樣它就不會影響下一個輸入操作。

示例以'hello', CTRL D和一個太大的字符串運行:

pax> ./qq
Enter string> hello
OK [hello]

pax> ./qq
Enter string>
No input

pax> ./qq
Enter string> dfgdfgjdjgdfhggh
Input too long

pax> _

對於它的價值(並且不要把它作為你自己的工作,因為你幾乎肯定會因為抄襲而被抓住 - 任何半正式的教育者都會在網上搜索你的代碼作為他們做的第一件事),這就是我如何接近它。

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

#define WORDLENGTH 15
#define MAXWORDS 1000

int main (void) {
    char *line[MAXWORDS];
    int numwords = 0;  // Use decent variable names.
    int chr, i;

    // Code to run until end of file.

    for (chr = getchar(); chr != EOF;) {           // First char.
        // This bit gets a word.

        char *tmp = malloc(WORDLENGTH + 1);        // Allocate space for word/NUL
        i = 0;
        while ((chr != ' ') && (chr != EOF)) {     // Read until space/EOF
            if (i < WORDLENGTH) {                  // If space left in word,
                tmp[i++] = chr;                    //   add it
                tmp[i] = '\0';                     //   and null-terminate.
            }
            chr = getchar();                       // Get next character.
        }
        line[numwords++] = tmp;                    // Store.

        // This bit skips space at end of word.

        while ((chr == ' ') && (chr != EOF)) {
            chr = getchar();
        }
    }

    // Now we have all our words, print them.

    for (i = 0; i < numwords; i++){
        printf ("%s\n", line[i]);
        free (line[i]);
    }

    return 0;
}

我建議你閱讀並仔細閱讀評論,以便你知道它是如何工作的。 請隨意在評論部分提出任何問題,我會回答或澄清。


這是一個示例運行:

pax$ echo 'hello   my name is pax andthisisaverylongword here' | ./testprog
hello
my
name
is
pax
andthisisaveryl
here

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM