为什么这段代码运行良好?它改变了常量存储区字符串;

Why does this code works well? It changes the Constant storage area string;

这是一个简单的 linux 内核模块代码,用于反转在 insmod 后应该 Oops 的字符串,但它运行良好,为什么?

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static char *words = "words";
static int __init words_init(void)
{
  printk(KERN_INFO "debug info\n");
  int  len = strlen(words);
  int  k;
  for ( k = 0; k < len/2; k++ )
  {
     printk("the value of k %d\n",k);
     char  a = words[k];
     words[k]= words[len-1-k];
     words[len-1-k]=a;        
 }
 printk(KERN_INFO "words is %s\n", words);
 return 0;
}
static void __exit words_exit(void)
{
  printk(KERN_INFO "words exit.\n");
}
module_init(words_init);
module_exit(words_exit);
module_param(words, charp, S_IRUGO);
MODULE_LICENSE("GPL");

static != const.

static 在您的示例中表示 "only visible in the current file"。参见 What does "static" mean?

const 就意味着 "the code which can see this declaration isn't supposed to change the variable"。但在某些情况下,您仍然可以创建指向相同地址的非常量指针并修改内容。

Space removal from a String - In Place C style with Pointers 建议写入字符串值是不可能的。

由于 static 是您的代码与问题代码之间的唯一区别,我进一步查看并发现:Global initialized variables declared as "const" go to text segment, while those declared "Static" go to data segment. Why?

尝试 static const char *word,应该可以。

哈哈,我自己从linux内核源码中得到答案;当你使用insmod时,它会调用init_moudle、load_module、strndup_usr 然后 memdup_usr 函数;memdup_usr 函数将使用 kmalloc_track_caller 从 slab 分配内存,然后使用 copy_from_usr 将模块参数复制到内核中;这意味着 linux 内核模块参数存储在堆中,而不是常量存储区!!所以我们可以改变它的内容!