簡體   English   中英

奇怪的字符*截斷

[英]Strange Char* Truncation

我剛剛回到C編程中,並且在結構中使用動態char *字段遇到一個奇怪的問題。 它起初完全正確,長度合適,但是它被截斷為25個字符,而最后一個甚至不在原始數組中。

我定義了兩個結構以及兩個全局變量:

struct files_list {
  struct files_list* next;
  char* fpath;
};

struct job_list {
  int len;
  off_t size;
  struct files_list* files;
  struct job_list* next;
};

struct job_list* job_head = NULL;
struct job_list* active = NULL;

(這個想法是,將有多個線程將處理的“作業”的單個鏈接列表,每個線程都包含該作業的單個文件鏈接列表。)

Main只是調用ntfw來遍歷目錄樹:

int main(int argc, char** argv) {
  // ...
  nftw("/tmp/", populate, 100, 0);
  // ...
}

對於每個文件和目錄,ntfw都會調用我的populate函數:

int populate(const char *fpath, const struct stat *sb,
             int tflag, struct FTW *ftwbuf) {



  if (tflag == FTW_F) {
    /* #1 CREATE NEW FILE ENTRY */
    printf("\n\n");
    printf("FPATH: %s\n", fpath);
    struct files_list* current_files = malloc(sizeof(struct files_list));
    current_files->fpath = malloc(sizeof(fpath) + 1);
    strcpy(current_files->fpath, fpath);
    current_files->next = NULL;
    printf("files_list %s (%i)\n", current_files->fpath, strlen(current_files->fpath)); 
    printf("&current_files: %p\n", current_files);



    /* #2 CREATE NEW ACTIVE JOB */
    if (active == NULL) {
      struct job_list* job = malloc(sizeof(struct job_list));
      job->len = 0;
      job->size = 0;
      job->files = NULL;
      job->next = NULL;
      active = job;
    }
    active->len++;
    active->size += sb->st_size;


    /* #3 INSERT FILE ENTRY AT THE END OF ACTIVE JOB */
    if (active->files == NULL) {
      active->files = current_files;
      printf("&active->files: %p\n", active->files);
      printf("current_files->fpath: %s (%i)\n", current_files->fpath, strlen(current_files->fpath)); // TRUNCATED STRING
      printf("active->files->fpath: %s (%i)\n", active->files->fpath, strlen(active->files->fpath));
    } else {                                                                                                                                                                                               
      struct files_list* x = active->files->next;                                                                                                                                                                  
      while (1) {                                                                                                                                                                                                  
        if (x == NULL) {                                                                                                                                                                                           
          x = current_files;                                                                                                                                                                                       
          printf("Added files_list: %s\n", x->fpath);                                                                                                                                                              
          break;                                                                                                                                                                                                   
        } else {                                                                                                                                                                                                   
          printf("next x->next\n");                                                                                                                                                                                
          x = x->next;                                                                                                                                                                                             
        }                                                                                                                                                                                                          
      }
    }

    /* #4 TIME FOR A NEW JOB */
    if (active->size > MAX_BYTES) {
      if (job_head == NULL) {
        job_head = active;
        job_tail = active;
      } else {
        job_tail->next = active;
      }
      struct job_list* new_active = NULL;
      active = new_active;
      job_len++;
    }
  }
  return 0;
}

產生這樣的輸出:

FPATH: /tmp/.com.google.Chrome.T8MuMk/SingletonSocket
files_list /tmp/.com.google.Chrome.T8MuMk/SingletonSocket (46)
&current_files: 0x125d1e0
&active->files: 0x125d1e0
current_files->fpath: /tmp/.com.google.Chrome.1 (25)
active->files->fpath: /tmp/.com.google.Chrome.1 (25)

從前兩行可以看出,文件路徑很長,包含46個字符,並且已成功strcpy() files_list到我的files_list結構中。 然后,在步驟#2和步驟#3的前幾行之間發生了一些事情,該過程將文件名截斷為24個字符並添加了“ 1”。 指針地址表明它仍然是相同的struct對象,並且我看不到任何可能使它混亂的操作。

我曾經使用過GCC 4.9.2和Clang 3.5.0,但它們都存在此問題,因此一定是我做錯了。

有什么想法嗎?

這就是問題

malloc(sizeof(fpath) + 1);

sizeof(fpath)將給出指針的大小,因為fpathchar *char指針,您需要strlen()

malloc(strlen(fpath) + 1);

不要忘記包含string.h

你需要閱讀有關sizeof操作符,這是從1570草案, 第6.5.3.4¶2。

sizeof運算符產生其操作數的大小(以字節為單位),該操作數可以是表達式或類型的括號名稱。 大小由操作數的類型確定。 結果是一個整數。 如果操作數的類型是可變長度數組類型,則對操作數求值; 否則,不評估操作數,結果為整數常量。

注意 :您必須檢查malloc()函數族的返回NULL ,發生故障時它們將返回NULL ,並且您必須檢查幾乎每個具有一個函數的返回值,因為這是確保該函數正常工作的唯一方法沒有意外發生,否則為什么會有返回值呢?

暫無
暫無

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

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