C中缓冲区的运算符地址

时间:2017-01-22 16:13:44

标签: c buffer-overflow

我正在阅读这本书"黑客:剥削艺术",我正在努力理解以下代码:

    int main(int argc, char *argv[]) { 
        int value = 5; 
        char buffer_one[8],buffer_two[8]; 
        strcpy(buffer_one, "one"); /* Put "one" into buffer_one. */ 
        strcpy(buffer_two, "two"); /* Put "two" intobuffer_two. */ 
        printf("[BEFORE] buffer_two is at %p and contains\'%s\'\n", buffer_two, buffer_two); 
        printf("[BEFORE] buffer_one is at %p and contains \'%s\'\n", buffer_one, buffer_one); 
        printf("[BEFORE] value is at %p and is %d (0x%08x)\n", &value, value, value);

我无法理解的是,在前两个printf语句中,我们没有使用运算符的地址,但是输出给出了内存地址,对于整数,我们为(&)运算符提供了地址。我已经用gdb检查过,如果我使用& buffer_two和& buffer_one,我得到相同的结果但是当我在最后一个printf语句中删除值之前的运算符地址时,我得到的输出是0x5。

2 个答案:

答案 0 :(得分:1)

好的,你即将从新手走向经验丰富的境界。 : - )

定义数组时,如buffer_one,名称&buffer_one是代表数组地址的标签。标签没有与之关联的地址,编制者选择实施&以提供与value相同的结果。

对于不是数组的值,情况并非如此,例如value&value包含值,value为您提供变量(*func_ptr)()的地址。

希望这能澄清事情。

顺便说一下,功能指针也一样。我们都知道函数指针的用法如下:func_ptr()来调用它指向的函数,但它的工作原理如下:char comment[100]; fp=fopen("/home/matthew/Desktop/BBE.txt","w"); printf("Enter, String: "); fgets(comment, sizeof comment, stdin); fputs(comment,fp);

答案 1 :(得分:0)

  

对于数组,数组名称本身对应于数组的第一个元素(array [0]),而不是intergers / float变量的情况。这就是为什么即使你把'&'运算符与数组。

这与我们处理从stdin读取字符串和整数值的方式类似。那里我们不需要& scanf中包含字符串的运算符。

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.CheckBoxListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class CheckBoxListCellExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        ListView<Document> listView = new ListView<>();

        StringConverter<Document> converter = new StringConverter<Document>() {

            @Override
            public String toString(Document document) {
                return document.getTitle();
            }

            // not actually used by CheckBoxListCell
            @Override
            public Document fromString(String string) {
                return null;
            }

        };

        listView.setCellFactory(CheckBoxListCell.forListView(Document::completedProperty, converter));

        for (int i = 1 ; i <= 20 ; i++) {
            listView.getItems().add(new Document("Document "+i, i%2==0));
        }

        Button markAllCompleted = new Button("Mark All Completed");
        markAllCompleted.setOnAction(e -> {
            for (Document doc : listView.getItems()) {
                doc.setCompleted(true);
            }
        });

        BorderPane root = new BorderPane(listView);
        BorderPane.setAlignment(markAllCompleted, Pos.CENTER);
        BorderPane.setMargin(markAllCompleted, new Insets(10));
        root.setBottom(markAllCompleted);
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static class Document {
        private final StringProperty title = new SimpleStringProperty();
        private final BooleanProperty completed = new SimpleBooleanProperty();

        public Document(String title, boolean completed) {
            setTitle(title);
            setCompleted(completed);
        }

        public final StringProperty titleProperty() {
            return this.title;
        }


        public final String getTitle() {
            return this.titleProperty().get();
        }


        public final void setTitle(final String title) {
            this.titleProperty().set(title);
        }


        public final BooleanProperty completedProperty() {
            return this.completed;
        }


        public final boolean isCompleted() {
            return this.completedProperty().get();
        }


        public final void setCompleted(final boolean completed) {
            this.completedProperty().set(completed);
        }



    }
    public static void main(String[] args) {
        launch(args);
    }
}